/*
Copyright (c) [2019年5月1日] [吴超]
[MBT_Studio] is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
		 http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
*/
#include "stdafx.h"
#include "数值变量.h"


#include "节点/插座/通用插座.h"
#include "节点/插座/几何插座.h"
#include "节点/插座/C_数值插座.h"
#include "节点/插座/C_单值矢量插座.h"
#include "节点/插座/list/list数值插座.h"
#include "节点/插座/list/list矢量插座.h"
#include "节点/节点树.h"

#include "节点/socket_utils.h"

#include "节点/数据/变量类JIT函数.h"
#include "节点数据声明.h"

#include <随机数.h>
#include <matXX.h>



C_变量引用节点::C_变量引用节点(S_设备环境& ctx) : C_节点基类(DEF_变量引用节点) {
	m_Ctx = ctx;
	m_Name = L"变量";

	C_插座基类* socket;
	DEF_创建引用插座_I(L"初始值");
	DEF_创建引用插座_I(L"赋值");
	DEF_创建引用插座_O(L"值");

	f_get输入插座(2)->f_set回写(true);
}

C_变量引用节点::~C_变量引用节点() {
}

bool C_变量引用节点::f_update() {
	return false;
}

std::string C_变量引用节点::f_编译(C_节点基类* rn, std::string& 声明, std::vector<std::string>& 定义, std::string& 释放) {
	f_su_插座类型切换到连入的插座类型(this, E_插座方向::e_插座Type_输入, 1);

	auto* socket = f_get输入插座(1);
	f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输入, 2, socket->m_Type);
	f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输出, 1, socket->m_Type);

	

	std::string name = f_getName() + "_变量引用";

	m_Code = socket->f_构建变量代码(0);
	m_Code += f_node_getDataTypeName(socket->m_Type) + "& " + name + " = " + socket->f_getCode(0) + ";\n";

	f_get输出插座(1)->f_setCode(name);

	if (m_区域父节点) {
		m_区域父节点->m_Code += m_Code;
		return "";
	}
	return m_Code;
}

C_节点基类* f_node_创建变量引用节点(S_设备环境& ctx, C_节点树* 子节点树) {
	return new C_变量引用节点(ctx);
}

C_节点基类* f_node_加载变量引用节点(S_设备环境& ctx, FILE* f) {
	C_变量引用节点* node = new C_变量引用节点(ctx);
	return node;
}

void f_node_保存变量引用节点(C_节点基类* n, FILE* f) {
	C_变量引用节点* node = dynamic_cast<C_变量引用节点*>(n);
}



C_I8变量节点::C_I8变量节点(S_设备环境& ctx) : C_节点基类(DEF_I8变量节点) {
	m_Ctx = ctx;
	m_Name = L"I8变量";


	C_插座基类* socket;
	DEF_创建iVec2插座_I(L"随机数范围");
	DEF_创建I32插座_I(L"随机种子");

	DEF_创建I8插座_O(L"值");

	(DEF_iVec2插座数据(f_get输入插座(1))) = { -1, 1 };
	(DEF_I32插座数据(f_get输入插座(2))) = 0;


	m_随机方式 = f_alloc_BoolProp(nullptr, L"随机");
	m_随机方式.m_私有 = true;
	f_prop_Bool(m_随机方式) = false;

	m_初始值 = f_alloc_I8Prop(nullptr, L"初始值");
	m_初始值.m_私有 = true;
	f_prop_I8(m_初始值) = 0;
}

C_I8变量节点::~C_I8变量节点() {
	f_prop_Release(m_随机方式);
}

bool C_I8变量节点::f_update() {
	
	auto& val = DEF_I8插座数据(f_get输出插座(1), 0);

	if (f_prop_Bool(m_随机方式)) {
		auto* socket1 = f_get输入插座(1);
		//auto* socket2 = f_get输入插座(2);

		ivec2 随机区间 = DEF_iVec2插座数据(socket1);
		int32 随机种子 = DEF_I32插座数据(f_get输入插座(2));

		val = f_random_I8(随机区间, 随机种子);
	}
	else {
		val = f_prop_I8(m_初始值);
	}

	return false;
}

std::string	C_I8变量节点::DEF_节点编译函数{
	m_Code = "";
	m_ReleaseCode = "";
	std::string name = f_getName();
	C_节点树* rt = f_getThis节点树();


	std::string 随机方式 = f_代码构建_属性变量(m_随机方式, rt);
	auto* socket1 = f_get输入插座(1);
	auto* socket2 = f_get输入插座(2);

	if (rt->m_树类型 == E_节点树类型::e_type_着色节点树) {
		m_Code += DEF_S(int)" " + name + " = 0;\n";

	}
	else {
		m_Code += DEF_S(int8)" " + name + ";\n";
		m_Code += "{\n";

		m_Code += socket1->f_构建变量代码(0);
		m_Code += socket2->f_构建变量代码(0);

		m_Code += "if(" + f_代码构建_属性变量(m_随机方式, f_getThis节点树()) + "){\n";
		m_Code += name + " = " + DEF_S(f_random_I8)"(" + socket1->f_getCode(0) + ", " + socket2->f_getCode(0) + ");\n";
		m_Code += "} else {\n";
		m_Code += name + " = " + f_代码构建_属性变量(m_初始值, f_getThis节点树()) + ";\n";
		m_Code += "}\n";

		m_Code += m_ReleaseCode;
		m_Code += "}\n";
	}


	f_get输出插座(1)->f_setCode(name);
	if (m_区域父节点) {
		m_区域父节点->m_Code += m_Code;
		return "";
	}
	return m_Code;
}

void C_I8变量节点::f_读取(FILE* f) {
	C_节点基类::f_读取(f);
	auto 文件块 = f_file_读取文件块(f);

	if (文件块.m_块类型 == E_节点工程文件块类型::e_工程文件块_节点实例属性) {
		const uint8* 下一次读取数据指针 = 文件块.m_data;
		下一次读取数据指针 = f_prop_Load(m_随机方式, 下一次读取数据指针);
		下一次读取数据指针 = f_prop_Load(m_初始值, 下一次读取数据指针);
	}

	free(文件块.m_data);
}

void C_I8变量节点::f_写入(FILE* f) {
	C_节点基类::f_写入(f);
	auto 文件块 = f_file_构建文件块信息(E_节点工程文件块类型::e_工程文件块_节点实例属性, S_节点数据::g_文件版本号);

	S_UI8Array* 块 = (S_UI8Array*)f_core_array_new(0, sizeof(uint8));
	f_prop_Save(m_随机方式, 块);
	f_prop_Save(m_初始值, 块);

	文件块.m_data = 块->ptr_userData;
	文件块.m_字节数 = 块->count;
	f_file_保存文件块(f, 文件块);

	f_core_array_free((S_Array*)块);
}

void C_I8变量节点::f_Copy(const C_节点基类* node) {
	C_节点基类::f_Copy(node);

	const C_I8变量节点* scr = dynamic_cast<const C_I8变量节点*>(node);
	if (scr) {
		f_prop_Bool(m_随机方式) = f_prop_Bool(scr->m_随机方式);
		f_prop_I8(m_初始值) = f_prop_I8(scr->m_初始值);
	}
}

C_节点基类* f_node_创建I8变量节点(S_设备环境& ctx, C_节点树* 子节点树) {
	return new C_I8变量节点(ctx);
}

C_节点基类* f_node_加载I8变量节点(S_设备环境& ctx, FILE* f) {
	C_I8变量节点* node = new C_I8变量节点(ctx);
	return node;
}

void		f_node_保存I8变量节点(C_节点基类* n, FILE* f) {
	C_I8变量节点* node = dynamic_cast<C_I8变量节点*>(n);
}




C_单值浮点变量节点::C_单值浮点变量节点(S_设备环境& ctx) : C_节点基类(DEF_浮点变量节点) {
	m_Ctx = ctx;
	m_Name = L"浮点变量";


	C_插座基类* socket;
	DEF_创建Vec2插座_I(L"随机数范围");
	DEF_创建UI32插座_I(L"随机种子");

	DEF_创建F32插座_v1_O(L"值");

	(DEF_Vec2插座数据(f_get输入插座(1), 0)) = {-100000, 100000};
	(DEF_UI32插座数据(f_get输入插座(2))) = 0;
	(DEF_F32插座数据(f_get输入插座(1))) = 0;


	m_位数 = f_alloc_EnumProp(nullptr, { {L"F16", ""}, {L"F32", ""}, {L"F64", ""}, {L"F128", ""} }, L"位数", 1);
	m_位数.m_私有 = true;

	m_是否随机 = f_alloc_BoolProp(nullptr, L"随机");
	m_是否随机.m_私有 = true;
	f_prop_Bool(m_是否随机) = false;

	m_值 = f_alloc_F32Prop(nullptr, L"值");
	m_值.m_私有 = true;
	f_prop_F32(m_值) = 0;

	m_常用量 = f_alloc_EnumProp(nullptr, { {L"PI", ""}, {L"2PI", ""}, {L"PI/2", ""}, {L"PI/4", ""} }, L"常用量", 1);
	m_常用量.m_私有 = true;


	f_构建代码_分配渲染器GPU属性变量(m_值);
}

C_单值浮点变量节点::~C_单值浮点变量节点() {
	f_prop_Release(m_位数);
	f_prop_Release(m_是否随机);
	f_prop_Release(m_值);

	f_构建代码_释放渲染器GPU属性变量(m_值);
}

void C_单值浮点变量节点::f_读取(FILE* f) {
	C_节点基类::f_读取(f);

	f_prop_Load(m_位数, f);
	f_prop_Load(m_是否随机, f);
	f_prop_Load(m_值, f);
}

void C_单值浮点变量节点::f_写入(FILE* f) {
	C_节点基类::f_写入(f);

	f_prop_Save(m_位数, f);
	f_prop_Save(m_是否随机, f);
	f_prop_Save(m_值, f);
}

bool C_单值浮点变量节点::f_update() {
	switch (f_prop_enum(m_位数))
	{
	case 0:
		f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输出, 1, E_值类型::e_Type_F16);
		break;
	case 1:
		f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输出, 1, E_值类型::e_Type_F32);
		break;
	case 2:
		f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输出, 1, E_值类型::e_Type_F64);
		break;
	case 3:
		f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输出, 1, E_值类型::e_Type_F128);
		break;
	default:
		break;
	}

	f_get输出插座(1)->f_setData(&f_prop_F32(m_值));

	return false;
}

std::string C_单值浮点变量节点::f_编译(C_节点基类* rn, std::string& 声明, std::vector<std::string>& 定义, std::string& 释放) {
	m_Code = "";
	std::string code;

	

	auto* socket1 = f_get输入插座(1);
	auto* socket2 = f_get输入插座(2);

	std::string 新变量 = f_getName();

	C_节点树* rt = f_getThis节点树();
	if (rt->m_树类型 == E_节点树类型::e_type_着色节点树) {
		m_Code += "float " + 新变量 + " = " + f_代码构建_属性变量(m_值, rt) + ";\n";
		//m_Code += "float " + 新变量 + " = 0;\n";
		if (m_值.m_GPU缓存[0].m_Buf) {
			f_buf_F32_at(m_值.m_GPU缓存[0]) = f_prop_F32(m_值);
		}
	}
	else {
		switch (f_prop_enum(m_位数)) {
		case 0: m_Code = "float16 "; break;
		case 1: m_Code = "float32 "; break;
		case 2: m_Code = "float64 "; break;
		case 3: m_Code = "float128 "; break;
		default:
			break;
		}

		m_Code += 新变量 + " = " + f_代码构建_属性变量(m_值, rt) + ";\n";
		m_Code += "{\n";

		m_Code += "if(" + f_代码构建_属性变量(m_是否随机, rt) + "){\n";
		m_Code += socket1->f_构建变量代码(0);
		m_Code += socket2->f_构建变量代码(0);
		m_Code += 新变量 + " = f_random_F32(" + socket2->f_getCode(0) + ", " + socket1->f_getCode(0) + ");\n";
		m_Code += "}\n";

		m_Code += m_ReleaseCode;
		m_Code += "}\n";
	}
	


	f_get输出插座(1)->f_setCode(新变量);

	if (m_区域父节点) {
		m_区域父节点->m_Code += m_Code;
		return "";
	}
	//f_get输出插座(1)->f_setCode(f_WStringToString(m_Name));
	return m_Code;
}

void C_单值浮点变量节点::f_Copy(const C_节点基类* node) {
	C_节点基类::f_Copy(node);

	const C_单值浮点变量节点* scr = dynamic_cast<const C_单值浮点变量节点*>(node);
	if (scr) {
		f_prop_Bool(m_是否随机) = f_prop_Bool(scr->m_是否随机);
		f_prop_F32(m_值) = f_prop_F32(scr->m_值);
	}
}

C_节点基类* f_node_创建单值浮点变量节点(S_设备环境& ctx, C_节点树* 子节点树) {
	return new C_单值浮点变量节点(ctx);
}

C_节点基类* f_node_加载单值浮点变量节点(S_设备环境& ctx, FILE* f) {
	C_单值浮点变量节点* node = new C_单值浮点变量节点(ctx);
	return node;
}

void f_node_保存单值浮点变量节点(C_节点基类* n, FILE* f) {
	C_单值浮点变量节点* node = dynamic_cast<C_单值浮点变量节点*>(n);
}






C_单值整数变量节点::C_单值整数变量节点(S_设备环境& ctx) : C_节点基类(DEF_整数变量节点) {
	m_Ctx = ctx;
	m_Name = L"整数变量";
	
	C_插座基类* socket;
	DEF_创建iVec2插座_I(L"随机数范围");
	DEF_创建UI32插座_I(L"随机种子");
	
	DEF_创建I32插座_O(L"值");


	DEF_iVec2插座数据(f_get输入插座(1)) = {-1000, 10000};
	(DEF_UI32插座数据(f_get输入插座(2))) = 0;
	//(DEF_I32插座数据(f_get输入插座(1))) = 0;



	std::vector<S_标题和图标> item = { 
		{L"I4", ""}, 
		{L"I8", ""}, 
		{L"I16", ""}, 
		{L"I32", ""}, 
		{L"I64", ""},
		{L"I128", ""},
		{L"UI4", ""},
		{L"UI8", ""},
		{L"UI16", ""},
		{L"UI32", ""},
		{L"UI64", ""},
		{L"UI128", ""},
	};
	m_位数 = f_alloc_EnumProp(nullptr, item, L"位数", 3);
	m_位数.m_私有 = true;

	m_是否随机 = f_alloc_BoolProp(nullptr, L"随机");
	m_是否随机.m_私有 = true;
	f_prop_Bool(m_是否随机) = false;

	m_值 = f_alloc_I32Prop(nullptr, L"值");
	m_值.m_私有 = true;
	f_prop_I32(m_值) = 0;

	f_构建代码_分配渲染器GPU属性变量(m_值);
}

C_单值整数变量节点::~C_单值整数变量节点() {
	f_prop_Release(m_位数);
	f_prop_Release(m_是否随机);
	f_prop_Release(m_值);

	f_构建代码_释放渲染器GPU属性变量(m_值);
}

void C_单值整数变量节点::f_读取(FILE* f) {
	C_节点基类::f_读取(f);

	f_prop_Load(m_位数, f);
	f_prop_Load(m_是否随机, f);
	f_prop_Load(m_值, f);
}

void C_单值整数变量节点::f_写入(FILE* f) {
	C_节点基类::f_写入(f);

	f_prop_Save(m_位数, f);
	f_prop_Save(m_是否随机, f);
	f_prop_Save(m_值, f);
}

bool C_单值整数变量节点::f_update() {
	switch (f_prop_enum(m_位数))
	{
	case 0:
		break;
	case 1:
		f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输出, 1, E_值类型::e_Type_I8);
		break;
	case 2:
		f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输出, 1, E_值类型::e_Type_I16);
		break;
	case 3:
		f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输出, 1, E_值类型::e_Type_I32);
		break;
	case 4:
		f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输出, 1, E_值类型::e_Type_I64);
		break;
	case 5:
		f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输出, 1, E_值类型::e_Type_I128);
		break;
	case 6:
		f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输出, 1, E_值类型::e_Type_UI4);
		break;
	case 7:
		f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输出, 1, E_值类型::e_Type_UI8);
		break;
	case 8:
		f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输出, 1, E_值类型::e_Type_UI16);
		break;
	case 9:
		f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输出, 1, E_值类型::e_Type_UI32);
		break;
	case 10:
		f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输出, 1, E_值类型::e_Type_UI64);
		break;
	case 11:
		f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输出, 1, E_值类型::e_Type_UI128);
		break;
	default:
		break;
	}

	auto* socket1 = f_get输入插座(1);
	auto* socket2 = f_get输入插座(2);

	if (f_prop_Bool(m_是否随机)) {
		int32 val = f_random_I32(DEF_iVec2插座数据(socket1), DEF_I32插座数据(socket2));
		f_get输出插座(1)->f_setData(&val);
	}
	else {
		f_get输出插座(1)->f_setData(&f_prop_I32(m_值));
	}
	//f_get输出插座(1)->f_绑定指针(m_值.m_Value);
	return false;
}

std::string C_单值整数变量节点::f_编译(C_节点基类* rn, std::string& 声明, std::vector<std::string>& 定义, std::string& 释放) {
	m_Code = "";
	m_ReleaseCode = "";
	auto name = f_getName();

	auto* socket1 = f_get输入插座(1);
	auto* socket2 = f_get输入插座(2);

	m_Code += socket1->f_构建变量代码(0);
	m_Code += socket2->f_构建变量代码(0);

	C_节点树* rt = f_getThis节点树();
	if (rt->m_树类型 == E_节点树类型::e_type_着色节点树) {
		m_Code += "int " + name + ";\n";

		if (m_值.m_GPU缓存[0].m_Buf) {
			f_buf_I32_at(m_值.m_GPU缓存[0], 0) = f_prop_I32(m_值);
		}
	}
	else {
		m_Code += "int32 " + name + ";\n";
		m_Code += "{\n";

		m_Code += "if(" + f_代码构建_属性变量(m_是否随机, rt) + "){\n";
		m_Code += name + " = " + DEF_S(f_random_I32)"(" + socket1->f_getCode(0) + ", " + socket2->f_getCode(0) + ");\n";
		m_Code += "} else {\n";
		m_Code += name + " = " + f_代码构建_属性变量(m_值, rt) + ";\n";
		m_Code += "}\n";

		m_Code += m_ReleaseCode;
		m_Code += "}\n";
	}
	
	
	
	f_get输出插座(1)->f_setCode(name);
	if (m_区域父节点) {
		m_区域父节点->m_Code += m_Code;
		return "";
	}
	return m_Code;
}

void C_单值整数变量节点::f_Copy(const C_节点基类* node) {
	C_节点基类::f_Copy(node);

	const C_单值整数变量节点* scr = dynamic_cast<const C_单值整数变量节点*>(node);
	if (scr) {
		f_prop_Bool(m_是否随机) = f_prop_Bool(scr->m_是否随机);
		f_prop_I32(m_值) = f_prop_I32(scr->m_值);
	}
}

C_节点基类* f_node_创建单值整数变量节点(S_设备环境& ctx, C_节点树* 子节点树) {
	return new C_单值整数变量节点(ctx);
}
C_节点基类* f_node_加载单值整数变量节点(S_设备环境& ctx, FILE* f) {
	C_单值整数变量节点* node = new C_单值整数变量节点(ctx);

	return node;
}
void f_node_保存单值整数变量节点(C_节点基类* n, FILE* f) {
	C_单值整数变量节点* node = dynamic_cast<C_单值整数变量节点*>(n);
}



C_无符号整数变量节点::C_无符号整数变量节点(S_设备环境& ctx) : C_节点基类(DEF_无符号整数变量节点) {
	m_Ctx = ctx;
	m_Name = L"整数变量";
	
	C_插座基类* socket;
	DEF_创建iVec2插座_I(L"随机数范围");
	DEF_创建UI32插座_I(L"随机种子");

	DEF_创建UI32插座_O(L"值");


	DEF_uVec2插座数据(f_get输入插座(1)) = { 0, 10000 };
	(DEF_UI32插座数据(f_get输入插座(2))) = 0;
	(DEF_UI32插座数据(f_get输入插座(1))) = 0;



	std::vector<S_标题和图标> item = {
		{L"UI4", ""},
		{L"UI8", ""},
		{L"UI16", ""},
		{L"UI32", ""},
		{L"UI64", ""},
		{L"UI128", ""},
	};
	m_位数 = f_alloc_EnumProp(nullptr, item, L"位数", 3);
	m_位数.m_私有 = true;

	m_是否随机 = f_alloc_BoolProp(nullptr, L"随机");
	m_是否随机.m_私有 = true;
	f_prop_Bool(m_是否随机) = false;

	m_值 = f_alloc_UI32Prop(nullptr, L"值");
	m_值.m_私有 = true;
	f_prop_UI32(m_值) = 0;

	m_标志位 = f_alloc_UI32FlagBitsProp((uint32*)m_值.m_Value, L"标志位");
	m_标志位.m_私有 = true;


}

C_无符号整数变量节点::~C_无符号整数变量节点() {
	f_prop_Release(m_位数);
	f_prop_Release(m_是否随机);
	f_prop_Release(m_值);
	f_prop_Release(m_标志位);
}

bool C_无符号整数变量节点::f_update() {
	switch (f_prop_enum(m_位数)) {
		case 0:
			f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输出, 1, E_值类型::e_Type_UI4);
			break;
		case 1:
			f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输出, 1, E_值类型::e_Type_UI8);
			break;
		case 2:
			f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输出, 1, E_值类型::e_Type_UI16);
			break;
		case 3:
			f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输出, 1, E_值类型::e_Type_UI32);
			break;
		case 4:
			f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输出, 1, E_值类型::e_Type_UI64);
			break;
		case 5:
			f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输出, 1, E_值类型::e_Type_UI128);
			break;
		default:
			break;
	}

	auto* socket1 = f_get输入插座(1);
	auto* socket2 = f_get输入插座(2);

	if (f_prop_Bool(m_是否随机)) {
		uint32 val = f_random_I32(DEF_iVec2插座数据(socket1), DEF_I32插座数据(socket2));
		f_get输出插座(1)->f_setData(&val);
	}
	else {
		f_get输出插座(1)->f_setData(&f_prop_UI32(m_值));
	}
	//f_get输出插座(1)->f_绑定指针(m_值.m_Value);
	return false;
}

std::string C_无符号整数变量节点::f_编译(C_节点基类* rn, std::string& 声明, std::vector<std::string>& 定义, std::string& 释放) {
	m_Code = "";
	m_ReleaseCode = "";
	auto name = f_getName();

	auto* socket1 = f_get输入插座(1);
	auto* socket2 = f_get输入插座(2);

	m_Code += socket1->f_构建变量代码(0);
	m_Code += socket2->f_构建变量代码(0);

	C_节点树* rt = f_getThis节点树();
	if (rt->m_树类型 == E_节点树类型::e_type_着色节点树) {
		m_Code += "int " + name + ";\n";


	}
	else {
		m_Code += "uint32 " + name + ";\n";
		m_Code += "{\n";

		m_Code += "if(" + f_代码构建_属性变量(m_是否随机, rt) + "){\n";
		m_Code += name + " = " + DEF_S(f_random_I32)"(" + socket1->f_getCode(0) + ", " + socket2->f_getCode(0) + ");\n";
		m_Code += "} else {\n";
		m_Code += name + " = " + f_代码构建_属性变量(m_值, rt) + ";\n";
		m_Code += "}\n";

		m_Code += m_ReleaseCode;
		m_Code += "}\n";
	}



	f_get输出插座(1)->f_setCode(name);
	if (m_区域父节点) {
		m_区域父节点->m_Code += m_Code;
		return "";
	}
	return m_Code;
}

void C_无符号整数变量节点::f_读取(FILE* f) {
	C_节点基类::f_读取(f);
	S_文件块 文件块 = f_file_读取文件块(f);
	if (文件块.m_块类型 == E_节点工程文件块类型::e_工程文件块_节点实例属性) {
		const uint8* 下一次读取数据指针 = 文件块.m_data;
		if (f_file_版本对比(文件块, S_节点数据::g_低版本号_0, S_节点数据::g_文件版本号)) {
			下一次读取数据指针 = f_prop_Load(m_位数, 下一次读取数据指针);
			下一次读取数据指针 = f_prop_Load(m_是否随机, 下一次读取数据指针);
			下一次读取数据指针 = f_prop_Load(m_值, 下一次读取数据指针);
		}
	}
	free(文件块.m_data);
}

void C_无符号整数变量节点::f_写入(FILE* f) {
	C_节点基类::f_写入(f);
	auto 文件块 = f_file_构建文件块信息(E_节点工程文件块类型::e_工程文件块_节点实例属性, S_节点数据::g_文件版本号);
	S_UI8Array* 块 = (S_UI8Array*)f_core_array_new(0, sizeof(uint8));

	f_prop_Save(m_位数, 块);
	f_prop_Save(m_是否随机, 块);
	f_prop_Save(m_值, 块);
	//f_prop_Save(m_标志位, 块);

	文件块.m_data = 块->ptr_userData;
	文件块.m_字节数 = 块->count;
	f_file_保存文件块(f, 文件块);
	f_core_array_free((S_Array*)块);
}

void C_无符号整数变量节点::f_Copy(const C_节点基类* node) {
	C_节点基类::f_Copy(node);

	const C_无符号整数变量节点* scr = dynamic_cast<const C_无符号整数变量节点*>(node);
	if (scr) {
		f_prop_Bool(m_是否随机) = f_prop_Bool(scr->m_是否随机);
		f_prop_UI32(m_值) = f_prop_UI32(scr->m_值);
	}
}

C_节点基类* f_node_创建无符号整数变量节点(S_设备环境& ctx, C_节点树* 子节点树) {
	return new C_无符号整数变量节点(ctx);
}
C_节点基类* f_node_加载无符号整数变量节点(S_设备环境& ctx, FILE* f) {
	C_无符号整数变量节点* node = new C_无符号整数变量节点(ctx);
	return node;
}
void f_node_保存无符号整数变量节点(C_节点基类* n, FILE* f) {
	C_无符号整数变量节点* node = dynamic_cast<C_无符号整数变量节点*>(n);
}




C_F32数组变量节点::C_F32数组变量节点(S_设备环境& ctx) : C_节点基类(DEF_F32数组变量节点) {
	m_Name = L"浮点数组";
	m_Ctx = ctx;

	C_插座基类* socket;
	DEF_创建UI32插座_I(L"数量");
	DEF_创建Vec2插座_I(L"范围", nullptr);
	DEF_创建I32插座_I(L"随机种子");

	DEF_创建F32_1D插座_O(L"值");

	(DEF_Vec2插座数据(f_get输入插座(2), 0)) = {0,1};
	(DEF_I32插座数据(f_get输入插座(3), 0)) = 0;


	m_位数 = f_alloc_EnumProp(nullptr, { {L"F32", ""}, {L"F64", ""} }, L"位宽类型");
	m_位数.m_私有 = true;

	m_随机方式 = f_alloc_EnumProp(nullptr, { {L"无", ""}, {L"随机", ""}, {L"钳制区间", ""}, {L"区间", ""} }, L"位宽类型");
	m_随机方式.m_私有 = true;

}

C_F32数组变量节点::~C_F32数组变量节点(){
	f_prop_Release(m_随机方式);
	f_prop_Release(m_位数);
}

bool C_F32数组变量节点::f_update() {
	auto* socket1 = f_get输入插座(1);
	auto* socket2 = f_get输入插座(2);
	auto* socket3 = f_get输入插座(3);

	auto* outSocket1 = f_get输出插座(1);

	auto 数量 = DEF_UI32插座数据(socket1);
	if(数量 >= -1) 数量 = 0;

	f_JIT_创建F32数组(DEF_F32插座_1D数据(outSocket1), DEF_UI32插座数据(socket1), f_prop_enum(m_随机方式), DEF_Vec2插座数据(socket2), DEF_I32插座数据(socket3));

	return false;
}

std::string C_F32数组变量节点::f_编译(C_节点基类* rn, std::string& 声明, std::vector<std::string>& 定义, std::string& 释放) {
	m_Code = "";
	m_ReleaseCode = "";
	std::string name = f_getName();
	C_节点树* rt = f_getThis节点树();


	std::string 位数 = f_代码构建_属性变量(m_位数, rt);
	auto* socket1 = f_get输入插座(1);
	auto* socket2 = f_get输入插座(2);
	auto* socket3 = f_get输入插座(3);

	if (rt->m_树类型 == E_节点树类型::e_type_着色节点树) {
		m_Code += DEF_S(float)" " + name + " = 0;\n";

	}
	else {
		m_Code += DEF_S(S_F32Array*)" " + name + " = " + f_代码构建_创建Array(E_值类型::e_Type_F32_1D, "1");
		m_Code += "{\n";

		m_Code += socket1->f_构建变量代码(0);
		m_Code += socket2->f_构建变量代码(0);
		m_Code += socket3->f_构建变量代码(0);

		m_Code += DEF_S(f_JIT_创建F32数组)"(" + name + ", " + socket1->f_getCode(0) + ", " + f_代码构建_属性变量(m_随机方式, rt) + ", " + socket2->f_getCode(0) + ", " + socket3->f_getCode(0) + ");\n";

		m_Code += m_ReleaseCode;
		m_Code += "}\n";
	}
	

	f_get输出插座(1)->f_setCode(name);
	if (m_区域父节点) {
		m_区域父节点->m_Code += m_Code;
		m_区域父节点->m_ReleaseCode = f_代码构建_销毁数组(name);
		return "";
	}
	释放 += f_代码构建_销毁数组(name);
	return m_Code;
}

void C_F32数组变量节点::f_读取(FILE* f) {
	C_节点基类::f_读取(f);
	f_prop_Load(m_随机方式, f);
	f_prop_Load(m_位数, f);
}

void C_F32数组变量节点::f_写入(FILE* f) {
	C_节点基类::f_写入(f);
	f_prop_Save(m_随机方式, f);
	f_prop_Save(m_位数, f);
}

C_节点基类* f_node_创建浮点数组变量节点(S_设备环境& ctx, C_节点树* 子节点树) {
	return new C_F32数组变量节点(ctx);
}

C_节点基类* f_node_加载浮点数组变量节点(S_设备环境& ctx, FILE* f) {
	C_F32数组变量节点* node = new C_F32数组变量节点(ctx);
	return node;
}

void f_node_保存浮点数组变量节点(C_节点基类* n, FILE* f) {
	C_F32数组变量节点* node = dynamic_cast<C_F32数组变量节点*>(n);
}





C_I32数组变量节点::C_I32数组变量节点(S_设备环境& ctx) : C_节点基类(DEF_I32数组变量节点) {
	m_Name = L"I32数组";
	m_Ctx = ctx;

	C_插座基类* socket;
	DEF_创建UI32插座_I(L"数量", nullptr);
	DEF_创建iVec2插座_I(L"范围", nullptr);
	DEF_创建I32插座_I(L"种子步进");

	DEF_创建I32_1D插座_O(L"变量");

	(DEF_UI32插座数据(f_get输入插座(1))) = 1;

	m_位数 = f_alloc_EnumProp(nullptr, { {L"无", ""}, {L"F32", ""}, {L"F64", ""} }, L"位宽类型");
	m_位数.m_私有 = true;

	m_随机方式 = f_alloc_EnumProp(nullptr, { {L"种子", ""}, {L"随机", ""}, {L"区间", ""}, {L"阶梯", ""} }, L"构建方式");
	m_随机方式.m_私有 = true;

	m_值 = f_alloc_I32Prop(nullptr, L"值");
	m_值.m_私有 = true;
}

C_I32数组变量节点::~C_I32数组变量节点() {
	f_prop_Release(m_值);
	f_prop_Release(m_随机方式);
	f_prop_Release(m_位数);
}

bool C_I32数组变量节点::f_update() {
	C_插座基类* socket1 = f_get输入插座(1);
	C_插座基类* socket2 = f_get输入插座(2);
	C_插座基类* socket3 = f_get输入插座(3);

	auto* outData = DEF_I32插座_1D数据(f_get输出插座(1));
	f_JIT_创建I32数组(outData, DEF_UI32插座数据(socket1), f_prop_enum(m_随机方式), DEF_iVec2插座数据(socket2), DEF_I32插座数据(socket3));
	return false;
}

std::string C_I32数组变量节点::DEF_节点编译函数{
	m_Code = "";
	m_ReleaseCode = "";
	std::string name = f_getName();
	auto* rt = f_getThis节点树();

	m_Code += DEF_S(S_I32Array*)" " + name + ";\n";
	
	C_插座基类* socket1 = f_get输入插座(1);
	C_插座基类* socket2 = f_get输入插座(2);
	C_插座基类* socket3 = f_get输入插座(3);

	m_Code += "{\n";
	m_Code += socket1->f_构建变量代码(0);
	m_Code += socket2->f_构建变量代码(0);
	m_Code += socket3->f_构建变量代码(0);

	m_Code += name + " = " + f_代码构建_创建Array(E_值类型::e_Type_I32_1D, "0");
	m_Code += DEF_S(f_JIT_创建I32数组)"(" + name + ", " + socket1->f_getCode(0) + ", " + f_代码构建_属性变量(m_随机方式, rt) + ", " + socket2->f_getCode(0) + ", " + socket3->f_getCode(0) + ");\n";

	m_Code += m_ReleaseCode;
	m_Code += "}\n";

	f_get输出插座(1)->f_setCode(name);
	if (m_区域父节点) {
		m_区域父节点->m_Code += m_Code;
		m_区域父节点->m_ReleaseCode = f_代码构建_销毁数组(name);
		return "";
	}
	释放 += f_代码构建_销毁数组(name);
	return m_Code;
}

void C_I32数组变量节点::f_读取(FILE* f) {
	C_节点基类::f_读取(f);
	f_prop_Load(m_值, f);
	f_prop_Load(m_随机方式, f);
	f_prop_Load(m_位数, f);
}

void C_I32数组变量节点::f_写入(FILE* f) {
	C_节点基类::f_写入(f);
	f_prop_Save(m_值, f);
	f_prop_Save(m_随机方式, f);
	f_prop_Save(m_位数, f);
}

C_节点基类* f_node_创建区间数组变量节点(S_设备环境& ctx, C_节点树* 子节点树) {
	return new C_I32数组变量节点(ctx);
}

C_节点基类* f_node_加载区间数组变量节点(S_设备环境& ctx, FILE* f) {
	C_I32数组变量节点* node = new C_I32数组变量节点(ctx);
	return node;
}

void f_node_保存区间数组变量节点(C_节点基类* n, FILE* f) {
	C_I32数组变量节点* node = dynamic_cast<C_I32数组变量节点*>(n);
}






C_UI32数组变量节点::C_UI32数组变量节点(S_设备环境& ctx) : C_节点基类(DEF_UI32数组变量节点) {
	m_Name = L"UI32数组";
	m_Ctx = ctx;

	C_插座基类* socket;
	DEF_创建UI32插座_I(L"数量", nullptr);
	DEF_创建iVec2插座_I(L"范围", nullptr);
	DEF_创建I32插座_I(L"种子步进");

	DEF_创建UI32_1D插座_O(L"变量");

	(DEF_UI32插座数据(f_get输入插座(1))) = 1;

	//m_位数 = f_alloc_EnumProp(nullptr, { {L"无", ""}, {L"F32", ""}, {L"F64", ""} }, L"位宽类型");
	//m_位数.m_私有 = true;

	m_随机方式 = f_alloc_EnumProp(nullptr, { {L"种子", ""}, {L"随机", ""}, {L"区间", ""}, {L"阶梯", ""} }, L"构建方式");
	m_随机方式.m_私有 = true;

	m_值 = f_alloc_UI32Prop(nullptr, L"值");
	m_值.m_私有 = true;
	f_prop_UI32(m_值) = 0;
}

C_UI32数组变量节点::~C_UI32数组变量节点() {
	f_prop_Release(m_值);
	f_prop_Release(m_随机方式);
}

bool C_UI32数组变量节点::f_update() {
	C_插座基类* socket1 = f_get输入插座(1);
	C_插座基类* socket2 = f_get输入插座(2);
	C_插座基类* socket3 = f_get输入插座(3);

	auto* outData = DEF_UI32插座_1D数据(f_get输出插座(1));
	f_JIT_创建UI32数组(outData, DEF_UI32插座数据(socket1), f_prop_enum(m_随机方式), DEF_iVec2插座数据(socket2), DEF_I32插座数据(socket3));
	return false;
}

std::string C_UI32数组变量节点::DEF_节点编译函数{
	m_Code = "";
	m_ReleaseCode = "";
	std::string name = f_getName();
	auto* rt = f_getThis节点树();

	m_Code += DEF_S(S_UI32Array*)" " + name + ";\n";

	C_插座基类* socket1 = f_get输入插座(1);
	C_插座基类* socket2 = f_get输入插座(2);
	C_插座基类* socket3 = f_get输入插座(3);

	m_Code += "{\n";
	m_Code += socket1->f_构建变量代码(0);
	m_Code += socket2->f_构建变量代码(0);
	m_Code += socket3->f_构建变量代码(0);

	m_Code += name + " = " + f_代码构建_创建Array(E_值类型::e_Type_UI32_1D, "0");
	m_Code += DEF_S(f_JIT_创建UI32数组)"(" + name + ", " + socket1->f_getCode(0) + ", " + f_代码构建_属性变量(m_随机方式, rt) + ", " + socket2->f_getCode(0) + ", " + socket3->f_getCode(0) + ");\n";

	m_Code += m_ReleaseCode;
	m_Code += "}\n";

	f_get输出插座(1)->f_setCode(name);
	if (m_区域父节点) {
		m_区域父节点->m_Code += m_Code;
		m_区域父节点->m_ReleaseCode = f_代码构建_销毁数组(name);
		return "";
	}
	释放 += f_代码构建_销毁数组(name);
	return m_Code;
}

void C_UI32数组变量节点::f_读取(FILE* f) {
	C_节点基类::f_读取(f);
	S_文件块 文件块 = f_file_读取文件块(f);
	if (文件块.m_块类型 == E_节点工程文件块类型::e_工程文件块_节点实例属性) {
		const uint8* 下一次读取数据指针 = 文件块.m_data;

		if (f_file_版本对比(文件块, S_节点数据::g_低版本号_0, S_节点数据::g_文件版本号)) {
			下一次读取数据指针 = f_prop_Load(m_值, 下一次读取数据指针);
			下一次读取数据指针 = f_prop_Load(m_随机方式, 下一次读取数据指针);
		}
	}
	free(文件块.m_data);
}

void C_UI32数组变量节点::f_写入(FILE* f) {
	C_节点基类::f_写入(f);
	S_文件块 文件块 = f_file_构建文件块信息(E_节点工程文件块类型::e_工程文件块_节点实例属性, S_节点数据::g_文件版本号);
	S_UI8Array* 块 = (S_UI8Array*)f_core_array_new(0, sizeof(uint8));

	f_prop_Save(m_值, 块);
	f_prop_Save(m_随机方式, 块);

	f_file_保存文件块(f, 文件块, 块);
}

void C_UI32数组变量节点::f_Copy(const C_节点基类* node) {
	C_节点基类::f_Copy(node);

	const C_UI32数组变量节点* scr = dynamic_cast<const C_UI32数组变量节点*>(node);
	if (scr) {
		f_prop_enum(m_随机方式) = f_prop_enum(scr->m_随机方式);
		f_prop_UI32(m_值) = f_prop_UI32(scr->m_值);
	}
}

C_节点基类* f_node_创建UI32数组变量节点(S_设备环境& ctx, C_节点树* 子节点树) {
	return new C_UI32数组变量节点(ctx);
}

C_节点基类* f_node_加载UI32数组变量节点(S_设备环境& ctx, FILE* f) {
	C_UI32数组变量节点* node = new C_UI32数组变量节点(ctx);
	return node;
}

void f_node_保存UI32数组变量节点(C_节点基类* n, FILE* f) {
	C_UI32数组变量节点* node = dynamic_cast<C_UI32数组变量节点*>(n);
}





C_vec2变量节点::C_vec2变量节点(S_设备环境& ctx) : C_节点基类(DEF_vec2变量节点) {
	m_Name = L"vec2";
	m_Ctx = ctx;

	C_插座基类* socket;
	DEF_创建I32插座_I(L"随机种子");

	DEF_创建F32插座_I(L"最小范围", nullptr);
	DEF_创建F32插座_I(L"最大范围", nullptr);

	DEF_创建Vec2插座_O(L"值");

	(DEF_F32插座数据(f_get输入插座(2), 0)) = 0;
	(DEF_F32插座数据(f_get输入插座(3), 0)) = 1;


	m_是否随机 = f_alloc_BoolProp(nullptr, L"是否随机");
	m_是否随机.m_私有 = true;

	
	m_Value = f_alloc_Vec2Prop(&DEF_Vec2插座数据(f_get输出插座(1), 0), L"val");
}

C_vec2变量节点::~C_vec2变量节点() {

}

bool C_vec2变量节点::f_update() {
	if (f_prop_Bool(m_是否随机)) {

	}
	return false;
}

std::string C_vec2变量节点::f_编译(C_节点基类* rn, std::string& 声明, std::vector<std::string>& 定义, std::string& 释放) {
	m_Code = "";
	auto* rt = f_getThis节点树();

	auto newVal = f_代码构建_属性变量(m_Value, rt);

	auto 是否随机 = f_代码构建_属性变量(m_是否随机, rt);
	m_Code += "if(" + 是否随机 + "){\n";

	auto 随机种子 = f_get输入插座(1)->f_构建变量代码(0);
	auto 最小范围 = f_get输入插座(2)->f_构建变量代码(0);
	auto 最大范围 = f_get输入插座(3)->f_构建变量代码(0);
	
	m_Code += newVal = "f_随机_向量(" + 最大范围 + ", " + ", " + 最大范围, +", " + 随机种子 + ");";

	m_Code += m_ReleaseCode;
	m_Code += "}\n";
	//m_Code += "else {\n";
	//m_Code += newVal = f_代码构建_属性变量(m_Value);
	//m_Code += "}\n";
	
	f_get输出插座(1)->f_setCode(newVal);

	if (m_区域父节点) {
		m_区域父节点->m_Code += m_Code;
		return "";
	}

	return m_Code;
}

void C_vec2变量节点::f_读取(FILE* f) {
	C_节点基类::f_读取(f);
	f_prop_Load(m_是否随机, f);
}

void C_vec2变量节点::f_写入(FILE* f) {
	C_节点基类::f_写入(f);
	f_prop_Save(m_是否随机, f);
}

C_节点基类* f_node_创建vec2变量节点(S_设备环境& ctx, C_节点树* 子节点树) {
	return new C_vec2变量节点(ctx);
}
C_节点基类* f_node_加载vec2变量节点(S_设备环境& ctx, FILE* f) {
	C_vec2变量节点* node = new C_vec2变量节点(ctx);

	return node;
}
void f_node_保存vec2变量节点(C_节点基类* n, FILE* f) {
	C_vec2变量节点* node = dynamic_cast<C_vec2变量节点*>(n);
}





C_vec3变量节点::C_vec3变量节点(S_设备环境& ctx) : C_节点基类(DEF_vec3变量节点) {
	m_Ctx = ctx;
	m_Name = L"vec3";

	C_插座基类* socket;

	//DEF_创建UI32插座_I(L"数量");
	DEF_创建UI32插座_I(L"种子");

	DEF_创建Vec2插座_I(L"X最小范围");
	DEF_创建Vec2插座_I(L"Y最大范围");
	DEF_创建Vec2插座_I(L"Z最大范围");

	DEF_创建Vec3插座_O(L"值");

	vec3 v = {};
	f_get输出插座(1)->f_setData(&v);

	(DEF_Vec2插座数据(f_get输入插座(2), 0)) = { 0, 1 };
	(DEF_Vec2插座数据(f_get输入插座(3), 0)) = { 0, 1 };
	(DEF_Vec2插座数据(f_get输入插座(4), 0)) = { 0, 1 };

	(DEF_Vec3插座数据(f_get输出插座(1), 0)) = { 0, 0, 0 };

	std::vector<S_标题和图标> item = {
		{L"F16", ""},
		{L"F32", ""},
		{L"F64", ""},
		{L"F128", ""},
	};

	m_是否随机 = f_alloc_BoolProp(nullptr, L"随机");
	m_是否随机.m_私有 = true;
	f_prop_Bool(m_是否随机) = false;

	//m_值 = f_alloc_Vec3Prop(nullptr, L"值");
	//m_值.m_私有 = true;
	//f_prop_Vec3(m_值) = {0,0,0};


	m_Value = f_alloc_Vec3Prop(&DEF_Vec3插座数据(f_get输出插座(1), 0), L"Value");
	m_Value.m_私有 = true;

	f_构建代码_分配渲染器GPU属性变量(m_Value);

}

C_vec3变量节点::~C_vec3变量节点() {
	f_prop_Release(m_Value);
	//f_prop_Release(m_值);
	f_prop_Release(m_是否随机);
}

bool C_vec3变量节点::f_update() {
	auto& outData = DEF_Vec3插座数据(f_get输出插座(1), 0);

	if (f_prop_Bool(m_是否随机)) {
		auto 种子 = DEF_UI32插座数据(f_get输入插座(1), 0);
		auto& inData1 = DEF_Vec2插座数据(f_get输入插座(2), 0);
		auto& inData2 = DEF_Vec2插座数据(f_get输入插座(3), 0);
		auto& inData3 = DEF_Vec2插座数据(f_get输入插座(4), 0);

		std::uniform_real_distribution<float32> disX(inData1.x, inData1.y);
		std::uniform_real_distribution<float32> disY(inData2.x, inData2.y);
		std::uniform_real_distribution<float32> disZ(inData3.x, inData3.y);
		std::default_random_engine e(种子);

		outData = vec3{ disX(e), disY(e), disZ(e) };
	}
	else {
		outData = f_prop_Vec3(m_Value);
	}

	return false;
}

std::string C_vec3变量节点::f_编译(C_节点基类* rn, std::string& 声明, std::vector<std::string>& 定义, std::string& 释放) {
	std::string code = f_getName() + "_vec3_val";

	C_节点树* rt = f_getThis节点树();

	switch (rt->m_树类型) {
	case E_节点树类型::e_type_着色节点树: {
		code = f_代码构建_属性变量(m_Value, rt);
		f_get输出插座(1)->f_setCode(code);

		((vec3*)m_Value.m_GPU缓存[0].m_Buf->m_mappedPtr)[m_Value.m_GPU缓存[0].m_Mem.m_偏移] = f_prop_Vec3(m_Value);
		break;
	}
	default:
		m_Code = "vec3 " + code + ";\n";
		m_Code += "{\n";

		m_Code += "if(" + f_代码构建_属性变量(m_是否随机, rt) + "){\n";

		m_Code += f_get输入插座(1)->f_构建变量代码(0);
		m_Code += f_get输入插座(2)->f_构建变量代码(0);
		m_Code += f_get输入插座(3)->f_构建变量代码(0);
		m_Code += f_get输入插座(4)->f_构建变量代码(0);

		m_Code += code + " = f_JIT_Fun_vec3_随机(" +
			f_get输入插座(1)->f_getCode(0) + ", " +
			f_get输入插座(2)->f_getCode(0) + ", " +
			f_get输入插座(3)->f_getCode(0) + ", " +
			f_get输入插座(4)->f_getCode(0) + ");\n";

		m_Code += "} else {\n";

		m_Code += code + " = " + f_代码构建_属性变量(m_Value, rt) + ";\n";

		m_Code += "}\n";

		f_get输出插座(1)->f_setCode(code);
		m_Code += m_ReleaseCode;
		m_Code += "}\n";
		break;
	}
	

	

	if (m_区域父节点) {
		m_区域父节点->m_Code += m_Code;
		return "";
	}
	return m_Code;
}

void C_vec3变量节点::f_读取(FILE* f) {
	C_节点基类::f_读取(f);
	f_prop_Load(m_Value, f);
	f_prop_Load(m_是否随机, f);
}

void C_vec3变量节点::f_写入(FILE* f) {
	C_节点基类::f_写入(f);
	f_prop_Save(m_Value, f);
	f_prop_Save(m_是否随机, f);
}

C_节点基类* f_node_创建vec3变量节点(S_设备环境& ctx, C_节点树* 子节点树) {
	return new C_vec3变量节点(ctx);
}

C_节点基类* f_node_加载vec3变量节点(S_设备环境& ctx, FILE* f) {
	C_vec3变量节点* node = new C_vec3变量节点(ctx);
	return node;
}

void f_node_保存vec3变量节点(C_节点基类* n, FILE* f) {
	C_vec3变量节点* node = dynamic_cast<C_vec3变量节点*>(n);
}







C_ivec3变量节点::C_ivec3变量节点(S_设备环境& ctx) : C_节点基类(DEF_ivec3变量节点) {
	m_Ctx = ctx;
	m_Name = L"ivec3";

	C_插座基类* socket;
	DEF_创建UI32插座_I(L"种子");

	DEF_创建iVec2插座_I(L"X最小范围");
	DEF_创建iVec2插座_I(L"Y最大范围");
	DEF_创建iVec2插座_I(L"Z最大范围");

	DEF_创建iVec3插座_O(L"值");

	vec3 v = {};
	f_get输出插座(1)->f_setData(&v);

	(DEF_Vec2插座数据(f_get输入插座(2), 0)) = { 0, 1 };
	(DEF_Vec2插座数据(f_get输入插座(3), 0)) = { 0, 1 };
	(DEF_Vec2插座数据(f_get输入插座(4), 0)) = { 0, 1 };

	DEF_Vec3插座数据(f_get输出插座(1)) = { 0, 0, 0 };

	//std::vector<S_标题和图标> item = {
	//	{L"F16", ""},
	//	{L"F32", ""},
	//	{L"F64", ""},
	//	{L"F128", ""},
	//};

	m_是否随机 = f_alloc_BoolProp(nullptr, L"随机");
	m_是否随机.m_私有 = true;
	f_prop_Bool(m_是否随机) = false;

	m_Value = f_alloc_iVec3Prop(nullptr, L"Value");
	m_Value.m_私有 = true;
	f_prop_iVec3(m_Value) = {0,0,0};


	f_构建代码_分配渲染器GPU属性变量(m_Value);

}

C_ivec3变量节点::~C_ivec3变量节点() {
	f_prop_Release(m_Value);
	f_prop_Release(m_是否随机);
}

bool C_ivec3变量节点::f_update() {
	auto& outData = DEF_iVec3插座数据(f_get输出插座(1));

	if (f_prop_Bool(m_是否随机)) {
		auto 种子 = DEF_UI32插座数据(f_get输入插座(1), 0);
		auto& inData1 = DEF_Vec2插座数据(f_get输入插座(2), 0);
		auto& inData2 = DEF_Vec2插座数据(f_get输入插座(3), 0);
		auto& inData3 = DEF_Vec2插座数据(f_get输入插座(4), 0);

		std::uniform_int_distribution<int32> disX(inData1.x, inData1.y);
		std::uniform_int_distribution<int32> disY(inData2.x, inData2.y);
		std::uniform_int_distribution<int32> disZ(inData3.x, inData3.y);
		std::default_random_engine e(种子);

		outData = ivec3{ disX(e), disY(e), disZ(e) };
	}
	else {
		outData = f_prop_iVec3(m_Value);
	}

	return false;
}

std::string C_ivec3变量节点::f_编译(C_节点基类* rn, std::string& 声明, std::vector<std::string>& 定义, std::string& 释放) {
	m_Code = "";
	m_ReleaseCode = "";

	std::string name = f_getName() + "_ivec3_val";

	C_节点树* rt = f_getThis节点树();

	switch (rt->m_树类型) {
		case E_节点树类型::e_type_着色节点树: {
			name = f_代码构建_属性变量(m_Value, rt);
			
			((ivec3*)m_Value.m_GPU缓存[0].m_Buf->m_mappedPtr)[m_Value.m_GPU缓存[0].m_Mem.m_偏移] = f_prop_iVec3(m_Value);
			break;
		}
		default:
			m_Code = "ivec3 " + name + ";\n";
			m_Code += "{\n";

			m_Code += "if(" + f_代码构建_属性变量(m_是否随机, rt) + "){\n";

				m_Code += f_get输入插座(1)->f_构建变量代码(0);
				m_Code += f_get输入插座(2)->f_构建变量代码(0);
				m_Code += f_get输入插座(3)->f_构建变量代码(0);
				m_Code += f_get输入插座(4)->f_构建变量代码(0);

				m_Code += name + " = " + DEF_S(f_JIT_Fun_ivec3_随机)"(" +
					f_get输入插座(1)->f_getCode(0) + ", " +
					f_get输入插座(2)->f_getCode(0) + ", " +
					f_get输入插座(3)->f_getCode(0) + ", " +
					f_get输入插座(4)->f_getCode(0) + ");\n";

			m_Code += "} else {\n";

				m_Code += name + " = " + f_代码构建_属性变量(m_Value, rt) + ";\n";

			m_Code += "}\n";

			
			m_Code += m_ReleaseCode;
			m_Code += "}\n";
			break;
	}


	f_get输出插座(1)->f_setCode(name);

	if (m_区域父节点) {
		m_区域父节点->m_Code += m_Code;
		return "";
	}
	return m_Code;
}

void C_ivec3变量节点::f_读取(FILE* f) {
	C_节点基类::f_读取(f);
	auto 文件块 = f_file_读取文件块(f);

	if (文件块.m_块类型 == E_节点工程文件块类型::e_工程文件块_节点实例属性) {
		const uint8* 下一次读取数据指针 = 文件块.m_data;
		下一次读取数据指针 = f_prop_Load(m_是否随机, 下一次读取数据指针);
		下一次读取数据指针 = f_prop_Load(m_Value, 下一次读取数据指针);
	}

	free(文件块.m_data);
}

void C_ivec3变量节点::f_写入(FILE* f) {
	C_节点基类::f_写入(f);
	auto 文件块 = f_file_构建文件块信息(E_节点工程文件块类型::e_工程文件块_节点实例属性, S_节点数据::g_文件版本号);

	S_UI8Array* 块 = (S_UI8Array*)f_core_array_new(0, sizeof(uint8));
	f_prop_Save(m_是否随机, 块);
	f_prop_Save(m_Value, 块);

	文件块.m_data = 块->ptr_userData;
	文件块.m_字节数 = 块->count;
	f_file_保存文件块(f, 文件块);

	f_core_array_free((S_Array*)块);
}

C_节点基类* f_node_创建ivec3变量节点(S_设备环境& ctx, C_节点树* 子节点树) {
	return new C_ivec3变量节点(ctx);
}

C_节点基类* f_node_加载ivec3变量节点(S_设备环境& ctx, FILE* f) {
	C_ivec3变量节点* node = new C_ivec3变量节点(ctx);
	return node;
}

void f_node_保存ivec3变量节点(C_节点基类* n, FILE* f) {
	C_ivec3变量节点* node = dynamic_cast<C_ivec3变量节点*>(n);
}





C_vec2数组变量节点::C_vec2数组变量节点(S_设备环境& ctx) : C_节点基类(DEF_vec2数组变量节点) {
	m_Name = L"[vec2]变量";


	C_插座基类* socket;
	DEF_创建UI32插座_I(L"数量");
	DEF_创建I32插座_I(L"随机种子");

	DEF_创建Vec2插座_I(L"最小范围");
	DEF_创建Vec2插座_I(L"最大范围");


	DEF_创建Vec3_Array1D插座_O(L"值");

	DEF_UI64插座Value(f_get输入插座(1), 0) = 1;
	(DEF_Vec2插座数据(f_get输入插座(3), 0)) = { -1, 1 };
	(DEF_Vec2插座数据(f_get输入插座(4), 0)) = { -1, 1 };


	m_是否随机 = f_alloc_BoolProp(nullptr, L"是否随机");
	m_是否随机.m_私有 = true;

}
C_vec2数组变量节点::~C_vec2数组变量节点() {

}

bool C_vec2数组变量节点::f_update() {
	auto 数量 = DEF_UI32插座数据(f_get输入插座(1), 0);

	auto& 数据 = *DEF_Vec2_Array1D插座数据(f_get输出插座(1), 0);


	if (f_prop_Bool(m_是否随机)) {
		auto 随机种子 = DEF_I32插座数据(f_get输入插座(2));
		auto& 随机范围 = DEF_Vec2插座数据(f_get输入插座(3), 0);
		f_随机向量(数据, 数量, 随机范围, 随机种子);
	}
	else {
		数据.resize(数量);
	}

	return false;
}

std::string C_vec2数组变量节点::f_编译(C_节点基类* rn, std::string& 声明, std::vector<std::string>& 定义, std::string& 释放) {

	return std::string();
}

void C_vec2数组变量节点::f_读取(FILE* f) {
	C_节点基类::f_读取(f);

	fread(&m_是否随机, sizeof(bool), 1, f);

}
void C_vec2数组变量节点::f_写入(FILE* f) {
	C_节点基类::f_写入(f);

	fwrite(&m_是否随机, sizeof(bool), 1, f);

}

C_节点基类* f_node_创建vec2数组变量节点(S_设备环境& ctx, C_节点树* 子节点树) {
	return new C_vec2数组变量节点(ctx);
}
C_节点基类* f_node_加载vec2数组变量节点(S_设备环境& ctx, FILE* f) {
	C_vec2数组变量节点* node = new C_vec2数组变量节点(ctx);
	return node;
}
void		f_node_保存vec2数组变量节点(C_节点基类* n, FILE* f) {
	C_vec2数组变量节点* node = dynamic_cast<C_vec2数组变量节点*>(n);
}






C_ivec2数组变量节点::C_ivec2数组变量节点(S_设备环境& ctx) : C_节点基类(DEF_ivec2数组变量节点) {
	m_Ctx = ctx;
	m_Name = L"ivec2数组";


	C_插座基类* socket;
	DEF_创建UI32插座_I(L"数量");
	DEF_创建iVec2插座_I(L"最小范围");
	DEF_创建iVec2插座_I(L"最大范围");
	DEF_创建I32插座_I(L"随机种子");

	DEF_创建iVec2_1D插座_O(L"值");

	DEF_UI64插座Value(f_get输入插座(1), 0) = 1;
	(DEF_iVec2插座数据(f_get输入插座(2))) = { 0, 0 };
	(DEF_iVec2插座数据(f_get输入插座(3))) = { 100, 100 };

	m_填充方式 = f_alloc_EnumProp(nullptr, {
		{L"种子", ""},
		{L"随机", ""},
		{L"区间", ""},
		{L"钳制区间", ""},
	}, L"填充方式");
	m_填充方式.m_私有 = true;
	f_prop_enum(m_填充方式) = 0;

	//m_是否无符号 = f_alloc_BoolProp(nullptr, L"无符号");
	//m_是否无符号.m_私有 = true;
	//f_prop_Bool(m_是否无符号) = false;
}

C_ivec2数组变量节点::~C_ivec2数组变量节点() {
	f_prop_Release(m_填充方式);
	//f_prop_Release(m_是否无符号);
}

bool C_ivec2数组变量节点::f_update() {
	auto 数量 = DEF_UI32插座数据(f_get输入插座(1), 0);
	
	auto* 数据 = DEF_iVec2插座_1D数据(f_get输出插座(1));


	auto& 最小范围 = DEF_iVec2插座数据(f_get输入插座(2));
	auto& 最大范围 = DEF_iVec2插座数据(f_get输入插座(3));
	auto 随机种子 = DEF_I32插座数据(f_get输入插座(5));
	f_random_iVec2Array(数据, 数量, 最小范围, 最大范围, 随机种子, f_prop_enum(m_填充方式));

	return false;
}

std::string C_ivec2数组变量节点::f_编译(C_节点基类* rn, std::string& 声明, std::vector<std::string>& 定义, std::string& 释放) {
	std::string code;
	std::string name;
	m_Code = "";
	m_ReleaseCode = "";

	C_节点树* rt = f_getThis节点树();

	name = f_getName();

	m_Code += DEF_S(S_iVec2Array*)" " + name + ";\n";
	m_Code += "{\n";

	for (uint32 i = 1; i < 5; ++i) {
		m_Code += f_get输入插座(i)->f_构建变量代码(0);
	}

	auto 数量 = f_get输入插座(1)->f_getCode(0);
	auto 最小范围 = f_get输入插座(2)->f_getCode(0);
	auto 最大范围 = f_get输入插座(3)->f_getCode(0);
	auto 种子 = f_get输入插座(4)->f_getCode(0);

	auto 填充方式 = f_代码构建_属性变量(m_填充方式, rt);

	m_Code += name + " = " + f_代码构建_创建Array(E_值类型::e_Type_iVec2_1D, 数量) + ";\n";
	m_Code += DEF_S(f_random_iVec2Array)"(" + name + "," + 数量 + ", " + 最小范围 + ", " + 最大范围 + ", " + 种子 + ", " + 填充方式 + ");\n";
	
	m_Code += m_ReleaseCode;
	m_Code += "}\n";

	f_get输出插座(1)->f_setCode(name);
	if (m_区域父节点) {
		m_区域父节点->m_Code;
		m_区域父节点->m_ReleaseCode += f_代码构建_销毁数组(name);
		return "";
	}
	释放 += f_代码构建_销毁数组(name);
	return m_Code;
}

void C_ivec2数组变量节点::f_读取(FILE* f) {
	C_节点基类::f_读取(f);
	auto 文件块 = f_file_读取文件块(f);

	if (文件块.m_块类型 == E_节点工程文件块类型::e_工程文件块_节点实例属性) {
		const uint8* 下一次读取数据指针 = 文件块.m_data;
		下一次读取数据指针 = f_prop_Load(m_填充方式, 下一次读取数据指针);
	}

	free(文件块.m_data);
}

void C_ivec2数组变量节点::f_写入(FILE* f) {
	C_节点基类::f_写入(f);
	auto 文件块 = f_file_构建文件块信息(E_节点工程文件块类型::e_工程文件块_节点实例属性, S_节点数据::g_文件版本号);

	S_UI8Array* 块 = (S_UI8Array*)f_core_array_new(0, sizeof(uint8));
	f_prop_Save(m_填充方式, 块);

	文件块.m_data = 块->ptr_userData;
	文件块.m_字节数 = 块->count;
	f_file_保存文件块(f, 文件块);
	f_core_array_free((S_Array*)块);
}

C_节点基类* f_node_创建ivec2数组变量节点(S_设备环境& ctx, C_节点树* 子节点树) {
	return new C_ivec2数组变量节点(ctx);
}

C_节点基类* f_node_加载ivec2数组变量节点(S_设备环境& ctx, FILE* f) {
	uint8 分量数量 = 0;
	C_ivec2数组变量节点* node = new C_ivec2数组变量节点(ctx);
	return node;
}

void f_node_保存ivec2数组变量节点(C_节点基类* n, FILE* f) {
	C_ivec2数组变量节点* node = dynamic_cast<C_ivec2数组变量节点*>(n);
}





//C_vec2数组变量节点::C_vec2数组变量节点(S_设备环境& ctx) : C_节点基类(DEF_vec2数组变量节点) {
//	m_Name = L"[vec2]变量";
//
//
//	C_插座基类* socket;
//	DEF_创建UI64插座_I(L"数量");
//	DEF_创建I32插座_I(L"随机种子");
//
//	DEF_创建Vec2插座_I(L"最小范围");
//	DEF_创建Vec2插座_I(L"最大范围");
//
//
//	DEF_创建Vec3_Array1D插座_O(L"值");
//
//	DEF_UI64插座Value(f_get输入插座(1), 0) = 1;
//	(*DEF_Vec2插座数据(f_get输入插座(3), 0)) = { -1, 1 };
//	(*DEF_Vec2插座数据(f_get输入插座(4), 0)) = { -1, 1 };
//
//
//	m_是否随机 = f_alloc_BoolProp(nullptr, L"是否随机");
//	m_是否随机.m_私有 = true;
//
//}
//C_vec2数组变量节点::~C_vec2数组变量节点() {
//
//}
//
//bool C_vec2数组变量节点::f_update() {
//	auto 数量 = DEF_UI64插座Value(f_get输入插座(1), 0);
//
//	auto& 数据 = *DEF_Vec2_Array1D插座数据(f_get输出插座(1), 0);
//
//
//	if (f_prop_Bool(m_是否随机)) {
//		auto 随机种子 = DEF_I32插座数据(f_get输入插座(2));
//		auto& 随机范围 = *DEF_Vec2插座数据(f_get输入插座(3), 0);
//		f_随机向量(数据, 数量, 随机范围, 随机种子);
//	}
//	else {
//		数据.resize(数量);
//	}
//
//	return false;
//}
//
//std::string C_vec2数组变量节点::f_编译(C_节点基类* rn, std::string& 声明, std::vector<std::string>& 定义, std::string& 释放) {
//
//	return std::string();
//}
//
//void C_vec2数组变量节点::f_读取(FILE* f) {
//	C_节点基类::f_读取(f);
//
//	fread(&m_是否随机, sizeof(bool), 1, f);
//
//}
//void C_vec2数组变量节点::f_写入(FILE* f) {
//	C_节点基类::f_写入(f);
//
//	fwrite(&m_是否随机, sizeof(bool), 1, f);
//
//}
//
//C_节点基类* f_node_创建vec2数组变量节点(S_设备环境& ctx, C_节点树* 子节点树) {
//	return new C_vec2数组变量节点(ctx);
//}
//C_节点基类* f_node_加载vec2数组变量节点(S_设备环境& ctx, FILE* f) {
//	C_vec2数组变量节点* node = new C_vec2数组变量节点(ctx);
//	return node;
//}
//void		f_node_保存vec2数组变量节点(C_节点基类* n, FILE* f) {
//	C_vec2数组变量节点* node = dynamic_cast<C_vec2数组变量节点*>(n);
//}



C_vec3数组变量节点::C_vec3数组变量节点(S_设备环境& ctx) : C_节点基类(DEF_vec3数组变量节点) {
	m_Ctx = ctx;
	m_Name = L"vec3Array";


	C_插座基类* socket;
	DEF_创建UI32插座_I(L"数量");
	DEF_创建Vec2插座_I(L"X随机范围");
	DEF_创建Vec2插座_I(L"Y随机范围");
	DEF_创建Vec2插座_I(L"Z随机范围");
	DEF_创建I32插座_I(L"随机种子");

	DEF_创建Vec3_1D插座_O(L"值");

	DEF_UI64插座Value(f_get输入插座(1), 0) = 1;
	(DEF_Vec2插座数据(f_get输入插座(2), 0)) = { 0, 1 };
	(DEF_Vec2插座数据(f_get输入插座(3), 0)) = { 0, 1 };
	(DEF_Vec2插座数据(f_get输入插座(4), 0)) = { 0, 1 };

	m_是否随机 = f_alloc_BoolProp(nullptr, L"是否随机");
	m_是否随机.m_私有 = true;
	f_prop_Bool(m_是否随机) = false;

}

C_vec3数组变量节点::~C_vec3数组变量节点() {
	f_prop_Release(m_是否随机);
}

void C_vec3数组变量节点::f_读取(FILE* f) {
	C_节点基类::f_读取(f);

	f_prop_Load(m_是否随机, f);
}

void C_vec3数组变量节点::f_写入(FILE* f) {
	C_节点基类::f_写入(f);

	f_prop_Save(m_是否随机, f);
}

bool C_vec3数组变量节点::f_update() {
	auto 数量 = DEF_UI32插座数据(f_get输入插座(1), 0);
	//数量 = DEF_Max(数量, 1);

	auto* 数据 = DEF_Vec3插座_1D数据(f_get输出插座(1));
	if (f_prop_Bool(m_是否随机)) {
		auto& X随机范围 = DEF_Vec2插座数据(f_get输入插座(2), 0);
		auto& Y随机范围 = DEF_Vec2插座数据(f_get输入插座(3), 0);
		auto& Z随机范围 = DEF_Vec2插座数据(f_get输入插座(4), 0);

		auto 随机种子 = DEF_I32插座数据(f_get输入插座(5));
		
		f_random_Vec3Array(数据, 数量, X随机范围, Y随机范围, Z随机范围, 随机种子);
	}
	else {
		f_core_array_resize((S_Array*)数据, 数量);
	}

	return false;
}

std::string C_vec3数组变量节点::f_编译(C_节点基类* rn, std::string& 声明, std::vector<std::string>& 定义, std::string& 释放) {
	std::string code;
	std::string name;
	m_Code = "";
	m_ReleaseCode = "";

	C_节点树* rt = f_getThis节点树();
	
	name = f_getName();

	m_Code += "S_Vec3Array* " + name + ";\n";
	m_Code += "{\n";

	for (uint32 i = 1; i < 6; ++i) {
		m_Code += f_get输入插座(i)->f_构建变量代码(0);
	}

	auto 数量 = f_get输入插座(1)->f_getCode(0);
	auto x范围 = f_get输入插座(2)->f_getCode(0);
	auto y范围 = f_get输入插座(3)->f_getCode(0);
	auto z范围 = f_get输入插座(4)->f_getCode(0);
	auto 种子 = f_get输入插座(5)->f_getCode(0);

	m_Code += name + " = " + f_代码构建_创建Array(E_值类型::e_Type_Vec3_1D, 数量) + ";\n";

	m_Code += "if(" + f_代码构建_属性变量(m_是否随机, rt) + "){\n";
	m_Code += DEF_S(f_random_Vec3Array)"(" + name + "," + 数量 + ", " + x范围 + ", " + y范围 + ", " + z范围 + ", " + 种子 + ");\n";
	m_Code += "}\n";

	m_Code += m_ReleaseCode;
	m_Code += "}\n";

	f_get输出插座(1)->f_setCode(name);
	if (m_区域父节点) {
		m_区域父节点->m_Code;
		m_区域父节点->m_ReleaseCode += f_代码构建_销毁数组(name);
		return "";
	}
	释放 += f_代码构建_销毁数组(name);
	return m_Code;

}

C_节点基类* f_node_创建vec3数组变量节点(S_设备环境& ctx, C_节点树* 子节点树) {
	return new C_vec3数组变量节点(ctx);
}

C_节点基类* f_node_加载vec3数组变量节点(S_设备环境& ctx, FILE* f) {
	uint8 分量数量 = 0;
	C_vec3数组变量节点* node = new C_vec3数组变量节点(ctx);
	return node;
}

void f_node_保存vec3数组变量节点(C_节点基类* n, FILE* f) {
	C_vec3数组变量节点* node = dynamic_cast<C_vec3数组变量节点*>(n);
}





C_ivec3数组变量节点::C_ivec3数组变量节点(S_设备环境& ctx) : C_节点基类(DEF_ivec3数组变量节点) {
	m_Ctx = ctx;
	m_Name = L"ivec3数组";


	C_插座基类* socket;
	DEF_创建UI32插座_I(L"数量");
	DEF_创建iVec3插座_I(L"最小范围");
	DEF_创建iVec3插座_I(L"最大范围");
	DEF_创建I32插座_I(L"随机种子");

	DEF_创建iVec3_1D插座_O(L"值");

	DEF_UI64插座Value(f_get输入插座(1), 0) = 1;
	(DEF_iVec3插座数据(f_get输入插座(2))) = { 0, 0, 0 };
	(DEF_iVec3插座数据(f_get输入插座(3))) = { 100, 100, 100 };

	m_是否随机 = f_alloc_BoolProp(nullptr, L"是否随机");
	m_是否随机.m_私有 = true;
	f_prop_Bool(m_是否随机) = false;

	m_是否无符号 = f_alloc_BoolProp(nullptr, L"无符号");
	m_是否无符号.m_私有 = true;
	f_prop_Bool(m_是否无符号) = false;
}

C_ivec3数组变量节点::~C_ivec3数组变量节点() {
	f_prop_Release(m_是否随机);
	f_prop_Release(m_是否无符号);
}

bool C_ivec3数组变量节点::f_update() {
	auto 数量 = DEF_UI32插座数据(f_get输入插座(1), 0);
	//数量 = DEF_Max(数量, 1);


	auto* 数据 = DEF_iVec3插座_1D数据(f_get输出插座(1));
	if (f_prop_Bool(m_是否随机)) {
		auto& 最小范围 = DEF_iVec3插座数据(f_get输入插座(2));
		auto& 最大范围 = DEF_iVec3插座数据(f_get输入插座(3));

		auto 随机种子 = DEF_I32插座数据(f_get输入插座(5));

		f_random_iVec3Array(数据, 数量, 最小范围, 最大范围, 随机种子);
	}
	else {
		f_core_array_resize((S_Array*)数据, 数量);
	}

	return false;
}

std::string C_ivec3数组变量节点::f_编译(C_节点基类* rn, std::string& 声明, std::vector<std::string>& 定义, std::string& 释放) {
	std::string code;
	std::string name;
	m_Code = "";
	m_ReleaseCode = "";

	C_节点树* rt = f_getThis节点树();

	name = f_getName();

	m_Code += DEF_S(S_iVec3Array*)" " + name + ";\n";
	m_Code += "{\n";

	for (uint32 i = 1; i < 5; ++i) {
		m_Code += f_get输入插座(i)->f_构建变量代码(0);
	}

	auto 数量 = f_get输入插座(1)->f_getCode(0);
	auto 最小范围 = f_get输入插座(2)->f_getCode(0);
	auto 最大范围 = f_get输入插座(3)->f_getCode(0);
	auto 种子 = f_get输入插座(4)->f_getCode(0);

	m_Code += name + " = " + f_代码构建_创建Array(E_值类型::e_Type_iVec3_1D, 数量) + ";\n";

	m_Code += "if(" + f_代码构建_属性变量(m_是否随机, rt) + "){\n";
	m_Code += DEF_S(f_random_iVec3Array)"(" + name + "," + 数量 + ", " + 最小范围 + ", " + 最大范围 + ", " + 种子 + ");\n";
	m_Code += "}\n";

	m_Code += m_ReleaseCode;
	m_Code += "}\n";

	f_get输出插座(1)->f_setCode(name);
	if (m_区域父节点) {
		m_区域父节点->m_Code;
		m_区域父节点->m_ReleaseCode += f_代码构建_销毁数组(name);
		return "";
	}
	释放 += f_代码构建_销毁数组(name);
	return m_Code;

}

void C_ivec3数组变量节点::f_读取(FILE* f) {
	C_节点基类::f_读取(f);
	auto 文件块 = f_file_读取文件块(f);

	if (文件块.m_块类型 == E_节点工程文件块类型::e_工程文件块_节点实例属性) {
		const uint8* 下一次读取数据指针 = 文件块.m_data;
		下一次读取数据指针 = f_prop_Load(m_是否随机, 下一次读取数据指针);
		下一次读取数据指针 = f_prop_Load(m_是否无符号, 下一次读取数据指针);
	}

	free(文件块.m_data);
}

void C_ivec3数组变量节点::f_写入(FILE* f) {
	C_节点基类::f_写入(f);
	auto 文件块 = f_file_构建文件块信息(E_节点工程文件块类型::e_工程文件块_节点实例属性, S_节点数据::g_文件版本号);

	S_UI8Array* 块 = (S_UI8Array*)f_core_array_new(0, sizeof(uint8));
	f_prop_Save(m_是否随机, 块);
	f_prop_Save(m_是否无符号, 块);

	文件块.m_data = 块->ptr_userData;
	文件块.m_字节数 = 块->count;
	f_file_保存文件块(f, 文件块);
	f_core_array_free((S_Array*)块);
}

C_节点基类* f_node_创建ivec3数组变量节点(S_设备环境& ctx, C_节点树* 子节点树) {
	return new C_ivec3数组变量节点(ctx);
}

C_节点基类* f_node_加载ivec3数组变量节点(S_设备环境& ctx, FILE* f) {
	uint8 分量数量 = 0;
	C_ivec3数组变量节点* node = new C_ivec3数组变量节点(ctx);
	return node;
}

void f_node_保存ivec3数组变量节点(C_节点基类* n, FILE* f) {
	C_ivec3数组变量节点* node = dynamic_cast<C_ivec3数组变量节点*>(n);
}






C_多边形成员数组变量节点::C_多边形成员数组变量节点(S_设备环境& ctx) : C_节点基类(DEF_多边形成员数组变量节点) {
	m_Ctx = ctx;
	m_Name = L"多边形成员";


	C_插座基类* socket;
	DEF_创建UI32插座_I(L"数量");

	DEF_创建多边形边_1D插座_O(L"值");
	//DEF_UI32插座Value(f_get输入插座(1), 0) = 1;

	m_成员 = f_alloc_EnumProp(nullptr, {
		{L"边", ""},
		{L"面", ""},
		{L"元素", ""},
	}, L"成员");
	m_成员.m_私有 = true;

	m_维度 = f_alloc_EnumProp(nullptr, {
		{L"一维", ""},
		{L"二维", ""},
		{L"三维", ""},
	}, L"维度");
	m_维度.m_私有 = true;
}

C_多边形成员数组变量节点::~C_多边形成员数组变量节点() {
	f_prop_Release(m_成员);
	f_prop_Release(m_维度);
}

bool C_多边形成员数组变量节点::f_update() {
	auto 数量 = DEF_UI32插座数据(f_get输入插座(1), 0);
	//数量 = DEF_Max(数量, 1);



	return false;
}

std::string C_多边形成员数组变量节点::f_编译(C_节点基类* rn, std::string& 声明, std::vector<std::string>& 定义, std::string& 释放) {
	std::string code;
	std::string name;
	m_Code = "";
	m_ReleaseCode = "";

	C_节点树* rt = f_getThis节点树();

	name = f_getName();

	auto* socket1 = f_get输入插座(1);

	m_Code += DEF_S(S_边Array*)" " + name + ";\n";
	m_Code += "{\n";
	socket1->f_构建变量代码(0);

	m_Code += name + " = " + f_代码构建_创建数组(E_值类型::e_Type_多边形边1D, 0);
	m_Code += DEF_S(f_core_array_resize)"((S_Array*)" + name + ", " + socket1->f_getCode(0) + ");\n";

	m_Code += m_ReleaseCode;
	m_Code += "}\n";

	f_get输出插座(1)->f_setCode(name);
	if (m_区域父节点) {
		m_区域父节点->m_Code;
		m_区域父节点->m_ReleaseCode += f_代码构建_销毁数组(name);
		return "";
	}
	释放 += f_代码构建_销毁数组(name);
	return m_Code;

}

void C_多边形成员数组变量节点::f_读取(FILE* f) {
	C_节点基类::f_读取(f);
	auto 文件块 = f_file_读取文件块(f);

	if (文件块.m_块类型 == E_节点工程文件块类型::e_工程文件块_节点实例属性) {
		if (f_file_版本对比(文件块, S_节点数据::g_低版本号_0, S_节点数据::g_文件版本号)) {
			const uint8* 下一次读取数据指针 = 文件块.m_data;
			下一次读取数据指针 = f_prop_Load(m_成员, 下一次读取数据指针);
			下一次读取数据指针 = f_prop_Load(m_维度, 下一次读取数据指针);
		}
	}

	free(文件块.m_data);
}

void C_多边形成员数组变量节点::f_写入(FILE* f) {
	C_节点基类::f_写入(f);
	auto 文件块 = f_file_构建文件块信息(E_节点工程文件块类型::e_工程文件块_节点实例属性, S_节点数据::g_文件版本号);

	S_UI8Array* 块 = (S_UI8Array*)f_core_array_new(0, sizeof(uint8));
	f_prop_Save(m_成员, 块);
	f_prop_Save(m_维度, 块);

	f_file_保存文件块(f, 文件块, 块);
}

C_节点基类* f_node_创建多边形成员数组变量节点(S_设备环境& ctx, C_节点树* 子节点树) {
	return new C_多边形成员数组变量节点(ctx);
}

C_节点基类* f_node_加载多边形成员数组变量节点(S_设备环境& ctx, FILE* f) {
	uint8 分量数量 = 0;
	C_多边形成员数组变量节点* node = new C_多边形成员数组变量节点(ctx);
	return node;
}

void f_node_保存多边形成员数组变量节点(C_节点基类* n, FILE* f) {
	C_多边形成员数组变量节点* node = dynamic_cast<C_多边形成员数组变量节点*>(n);
}





C_vec球数组节点::C_vec球数组节点(S_设备环境& ctx) : C_节点基类("vec球数组节点") {
	m_Name = L"[vec]球节点";


	C_插座基类* socket;
	DEF_创建UI64插座_I(L"数量");
	DEF_创建I32插座_I(L"随机种子");
	DEF_创建Vec3插座_v1_I(L"坐标最小范围");
	DEF_创建Vec3插座_v1_I(L"坐标最大范围");

	DEF_创建Vec2插座_I(L"半径范围");


	DEF_创建VecSphere_1D_插座_O(L"值");




	vec3 范围value = { -1,-1,-1 };
	f_get输入插座(3)->f_setData(&范围value);
	范围value = { 1, 1, 1 };
	f_get输入插座(4)->f_setData(&范围value);

	vec2 半径范围 = { 0.5f, 1.0f };
	f_get输入插座(5)->f_setData(&半径范围);


	m_是否随机 = f_alloc_BoolProp(nullptr, L"是否随机");
	m_是否随机.m_私有 = true;
	f_prop_Bool(m_是否随机) = false;
}

C_vec球数组节点::~C_vec球数组节点() {

}

bool C_vec球数组节点::f_update() {
	auto 数量 = DEF_UI64插座Value(f_get输入插座(1), 0);

	auto& 数据 = *DEF_VecSphere_1D插座数据(f_get输出插座(1));

	if (f_prop_Bool(m_是否随机)) {
		auto 随机种子 = DEF_I32插座数据(f_get输入插座(2));

		const auto& 最小值 = DEF_Vec3插座数据(f_get输入插座(3));
		const auto& 最大值 = DEF_Vec3插座数据(f_get输入插座(4));
		const auto& 半径范围 = DEF_Vec2插座数据(f_get输入插座(5), 0);

		f_随机向量(数据, 数量, S_VecSphere{ 最小值, 半径范围.x }, S_VecSphere{ 最大值, 半径范围.y }, 随机种子);
	}
	else {
		数据.resize(数量);
	}

	return false;
}

void C_vec球数组节点::f_读取(FILE* f) {
	C_节点基类::f_读取(f);
	f_prop_Load(m_是否随机, f);
}

void C_vec球数组节点::f_写入(FILE* f) {
	C_节点基类::f_写入(f);
	f_prop_Save(m_是否随机, f);
}

C_节点基类* f_node_创建vec球数组节点(S_设备环境& ctx, C_节点树* 子节点树) {
	return new C_vec球数组节点(ctx);
}

C_节点基类* f_node_加载vec球数组节点(S_设备环境& ctx, FILE* f) {
	C_vec球数组节点* node = new C_vec球数组节点(ctx);
	return node;
}

void f_node_保存vec球数组节点(C_节点基类* n, FILE* f) {
	C_vec球数组节点* node = dynamic_cast<C_vec球数组节点*>(n);
}








C_矩阵数组变量节点::C_矩阵数组变量节点(S_设备环境& ctx) : C_节点基类(DEF_44矩阵数组变量节点) {
	m_Ctx = ctx;
	m_Name = L"[矩阵变量]";

	m_是否取随机数 = false;


	C_插座基类* socket;
	DEF_创建Vec3_1D插座_I(L"移动");
	DEF_创建Vec3_1D插座_I(L"旋转");
	DEF_创建Vec3_1D插座_I(L"缩放");
	DEF_创建UI32插座_I(L"数量");
	
	DEF_创建Mat4X4_1D插座_O(L"矩阵");

	(DEF_UI32插座数据(f_get输入插座(4), 0)) = 1;
}

C_矩阵数组变量节点::~C_矩阵数组变量节点() {

}

void C_矩阵数组变量节点::f_读取(FILE* f) {
	C_节点基类::f_读取(f);
}

void C_矩阵数组变量节点::f_写入(FILE* f) {
	C_节点基类::f_写入(f);
}

bool C_矩阵数组变量节点::f_update() {
	auto* l = DEF_Vec3插座_1D数据(f_get输入插座(1), 0);
	auto* r = DEF_Vec3插座_1D数据(f_get输入插座(2), 0);
	auto* s = DEF_Vec3插座_1D数据(f_get输入插座(3), 0);

	uint32 num = DEF_UI32插座数据(f_get输入插座(4), 0);

	auto* mats = DEF_Mat44插座_1D数据(f_get输出插座(1), 0);
	f_core_array_resize((S_Array*)mats, num);
	

	bool 移动单例 = true;
	bool 旋转单例 = true;
	bool 缩放单例 = true;
	if (l->count >= num) 移动单例 = false;
	if (r->count >= num) 旋转单例 = false;
	if (s->count >= num) 缩放单例 = false;

	auto* mats_ptr = mats->ptr_userData;
	auto* l_ptr = l->ptr_userData;;
	auto* r_ptr = r->ptr_userData;;
	auto* s_ptr = s->ptr_userData;;
	for (int32 i = 0; i < num; ++i) {
		S_Tranform t;
		if (移动单例) t.location = l_ptr[0];
		else t.location = l_ptr[i];

		if (移动单例) t.rotation = r_ptr[0];
		else t.rotation = r_ptr[i];

		if (移动单例) t.scale = s_ptr[0];
		else t.scale = s_ptr[i];

		mats_ptr[i] = f_mat44_构建XYZ变换矩阵(t);
	}
	
	return false;
}


C_节点基类* f_node_创建矩阵数组变量节点(S_设备环境& ctx, C_节点树* 子节点树) {
	return new C_矩阵数组变量节点(ctx);
}

C_节点基类* f_node_加载矩阵数组变量节点(S_设备环境& ctx, FILE* f) {
	C_矩阵数组变量节点* node = new C_矩阵数组变量节点(ctx);
	return node;
}

void f_node_保存矩阵数组变量节点(C_节点基类* n, FILE* f) {
	C_矩阵数组变量节点* node = dynamic_cast<C_矩阵数组变量节点*>(n);
}












C_矩阵构建节点::C_矩阵构建节点(S_设备环境& ctx) : C_节点基类(DEF_矩阵构建节点) {
	m_Name = L"矩阵构建";
	m_Ctx = ctx;

	C_插座基类* socket;
	DEF_创建Vec3_1D插座_I(L"向量", nullptr);
	DEF_创建F32_1D插座_I(L"角度", nullptr);

	DEF_创建Mat4X4_1D插座_O(L"矩阵");


	auto& l = *DEF_Vec3插座_1D数据(f_get输入插座(1));
	l.ptr_userData[0] = {0,0,0};
	auto& a = *DEF_F32插座_1D数据(f_get输入插座(2));
	a.ptr_userData[0] = 0;



	m_矩阵类型 = f_alloc_EnumProp(nullptr,
		//	0					1					2					3					4	
		{ {L"移动矩阵", ""}, {L"缩放矩阵", ""}, {L"旋转矩阵", ""}, {L"欧拉矩阵", ""},  },
		L"矩阵类型",
		0,
		nullptr
	);
	m_矩阵类型.m_私有 = true;

	m_轴向 = f_alloc_EnumProp(nullptr,
		//	0			1			2			3			4
		{ {L"X", ""}, {L"Y", ""}, {L"Z", ""} },
		L"矩阵类型",
		0,
		nullptr
	);
	m_轴向.m_私有 = true;


	m_方向 = f_alloc_Vec3Prop(nullptr, L"轴向");
	m_方向.m_私有 = true;
	m_角度 = f_alloc_F32Prop(nullptr, L"角度");
	m_角度.m_私有 = true;

	f_prop_Vec3(m_方向) = { 0,0,0 };
	f_prop_F32(m_角度) = 1;
}

C_矩阵构建节点::~C_矩阵构建节点() {
	f_prop_Release(m_矩阵类型);
	f_prop_Release(m_轴向);
}

bool C_矩阵构建节点::f_update() {
	auto* 向量 = DEF_Vec3插座_1D数据(f_get输入插座(1));

	auto* socket1 = f_get输入插座(1);
	auto* socket2 = f_get输入插座(2);
	if (socket1->f_isLink() == false) {
		向量->ptr_userData[0] = f_prop_Vec3(m_方向);
	}

	auto* 角度 = DEF_F32插座_1D数据(socket2);
	if (socket2->f_isLink() == false) {
		角度->ptr_userData[0] = f_prop_F32(m_角度);
	}
	
	
	auto* 输出矩阵 = DEF_Mat44插座_1D数据(f_get输出插座(1), 0);

	uint32 num = DEF_Max(角度->count, 向量->count);

	bool 角度单例 = 角度->count < num;
	bool 向量单例 = 向量->count < num;


	f_core_array_resize((S_Array*)输出矩阵, num);
	if (!num) return true;

	switch (f_prop_enum(m_矩阵类型)) {
	case 0: {
		for (uint32 i = 0; i < num; ++i) {
			if (向量单例) {
				输出矩阵->ptr_userData[i] = f_mat44_构建移动矩阵(向量->ptr_userData[0]);
			}
			else {
				输出矩阵->ptr_userData[i] = f_mat44_构建移动矩阵(向量->ptr_userData[i]);
			}
		}

		break;
	}
	case 1: {
		for (uint32 i = 0; i < num; ++i) {
			if (向量单例) {
				输出矩阵->ptr_userData[i] = f_mat44_构建缩放矩阵(向量->ptr_userData[0]);
			}
			else {
				输出矩阵->ptr_userData[i] = f_mat44_构建缩放矩阵(向量->ptr_userData[i]);
			}
		}
		break;
	}
	case 2: {
		for (uint32 i = 0; i < num; ++i) {
			vec3 d;
			if (向量单例) {
				d = 向量->ptr_userData[0];
			}
			else {
				d = 向量->ptr_userData[i];
			}
			float32 angle;
			if (角度单例) {
				angle = 角度->ptr_userData[0];
			}
			else {
				angle = 角度->ptr_userData[i];
			}
			//std::cout<<angle<<std::endl;
			输出矩阵->ptr_userData[i] = f_mat44_构建行式旋转矩阵(d, angle);
		}

		break;
	}
	case 3: {
		typedef Mat44f (*fn_mat44_构建X旋转矩阵)(float32 a);
		fn_mat44_构建X旋转矩阵 fu = f_mat44_构建X旋转矩阵;
		switch (f_prop_enum(m_轴向)) {
			case 1: {
				fu = f_mat44_构建Y旋转矩阵;
				break;
			}
			case 2: {
				fu = f_mat44_构建Z旋转矩阵;
				break;
			}
		}
		
		for (uint32 i = 0; i < num; ++i) {
			float32 angle;
			if (角度单例) {
				angle = 角度->ptr_userData[0];
			}
			else {
				angle = 角度->ptr_userData[i];
			}
			输出矩阵->ptr_userData[i] = fu(angle);
		}
		break;
	}

	}

	return false;
}

std::string C_矩阵构建节点::f_编译(C_节点基类* rn, std::string& 声明, std::vector<std::string>& 定义, std::string& 释放) {
	m_Code = "";
	m_ReleaseCode = "";

	C_节点树* rt = f_getThis节点树();
	std::string 新变量;
	新变量 = f_getName();


	C_插座基类* socket1 = f_get输入插座(1);
	if (socket1->m_Type == E_值类型::e_Type_Vec3_Array1D) {
		f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输入, 1, E_值类型::e_Type_Vec3_1D);
		f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输入, 2, E_值类型::e_Type_F32_1D);
		
		socket1 = f_get输入插座(1);
	}
	f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输出, 1, E_值类型::e_Type_Mat4X4_1D);


	C_插座基类* socket2 = f_get输入插座(2);


	m_Code += "S_Mat44Array* " + 新变量 + ";\n";


	m_Code += "{\n";
	m_Code += socket1->f_构建变量代码(0);
	m_Code += socket2->f_构建变量代码(0);



	std::string 参数[2];

	if (socket1->f_isLink()) {
		参数[0] = socket1->f_getCode(0);
	}
	else {
		参数[0] = 新变量 + "_向量";
		m_Code += "S_Vec3Array* " + 参数[0] + " = f_vec3_array_fromV3_alloc(" + f_代码构建_属性变量(m_方向, rt) + ");\n";
		m_ReleaseCode += f_代码构建_销毁数组(参数[0]);
	}

	if (socket2->f_isLink()) {
		参数[1] = socket2->f_getCode(0);
	}
	else {
		参数[1] = 新变量 + "参数1";
		m_Code += "S_F32Array* " + 参数[1] + " = f_f32_array_fromF32_alloc(" + f_代码构建_属性变量(m_角度, rt) + ");\n";
		m_ReleaseCode += f_代码构建_销毁数组(参数[1]);
	}

	auto 矩阵类型 = f_代码构建_属性变量(m_矩阵类型, rt);

	m_Code += 新变量 + " = " + "f_JIT_Fun_mat_构建矩阵(" + 参数[0] + ", " + 参数[1] + ", " + 矩阵类型 + ");\n";

	f_get输出插座(1)->f_setCode(新变量);

	m_Code += m_ReleaseCode;
	m_Code += "}\n";

	if (m_区域父节点) {
		m_区域父节点->m_Code += m_Code;
		m_区域父节点->m_ReleaseCode += f_代码构建_销毁数组(新变量);
		return "";
	}
	释放 += f_代码构建_销毁数组(新变量);
	return m_Code;
}

void C_矩阵构建节点::f_读取(FILE* f) {
	C_节点基类::f_读取(f);

	f_prop_Load(m_矩阵类型, f);
	f_prop_Load(m_轴向, f);
	f_prop_Load(m_方向, f);
	f_prop_Load(m_角度, f);
}

void C_矩阵构建节点::f_写入(FILE* f) {
	C_节点基类::f_写入(f);

	f_prop_Save(m_矩阵类型, f);
	f_prop_Save(m_轴向, f);
	f_prop_Save(m_方向, f);
	f_prop_Save(m_角度, f);
}

C_节点基类* f_node_创建矩阵构建节点(S_设备环境& ctx, C_节点树* 子节点树) {
	return new C_矩阵构建节点(ctx);
}

C_节点基类* f_node_加载矩阵构建节点(S_设备环境& ctx, FILE* f) {
	C_矩阵构建节点* node = new C_矩阵构建节点(ctx);
	return node;
}

void f_node_保存矩阵构建节点(C_节点基类* n, FILE* f) {
	C_矩阵构建节点* node = dynamic_cast<C_矩阵构建节点*>(n);
}





C_Vec4数组节点::C_Vec4数组节点(S_设备环境& ctx) : C_节点基类(DEF_Vec4数组变量节点) {
	m_Name = L"vec4数组";
	m_Ctx = ctx;

	C_插座基类* socket;
	DEF_创建UI32插座_I(L"数量");
	DEF_创建Vec2插座_I(L"X随机");
	DEF_创建Vec2插座_I(L"Y随机");
	DEF_创建Vec2插座_I(L"Z随机");

	DEF_创建Vec4_1D插座_O(L"数组");

	(DEF_UI32插座数据(f_get输入插座(1))) = 1;

	m_是否随机 = f_alloc_BoolProp(nullptr, L"随机");
	m_是否随机.m_私有 = true;
	f_prop_Bool(m_是否随机) = false;
	
}

C_Vec4数组节点::~C_Vec4数组节点() {
	f_prop_Release(m_是否随机);
}

bool C_Vec4数组节点::f_update() {
	return false;
}

std::string C_Vec4数组节点::DEF_节点编译函数 {
	m_Code = "";
	m_ReleaseCode = "";
	C_节点树* rt = f_getThis节点树();
	std::string name = f_getName();

	C_插座基类* socket1 = f_get输入插座(1);
	m_Code += socket1->f_构建变量代码(0);

	m_Code += DEF_S(S_Vec4Array*)" " + name + " = " + f_代码构建_创建Array(E_值类型::e_Type_Vec4_1D, socket1->f_getCode(0));

	f_get输出插座(1)->f_setCode(name);
	if (m_区域父节点) {
		m_区域父节点->m_Code += m_Code;
		m_区域父节点->m_ReleaseCode += f_代码构建_销毁数组(name);
		return "";
	}
	释放 += f_代码构建_销毁数组(name);
	return m_Code;
}

void C_Vec4数组节点::f_读取(FILE* f) {
	C_节点基类::f_读取(f);
	f_prop_Load(m_是否随机, f);
}

void C_Vec4数组节点::f_写入(FILE* f) {
	C_节点基类::f_写入(f);
	f_prop_Save(m_是否随机, f);
}

C_节点基类* f_node_创建Vec4数组节点(S_设备环境& ctx, C_节点树* 子节点树) {
	return new C_Vec4数组节点(ctx);
}

C_节点基类* f_node_加载Vec4数组节点(S_设备环境& ctx, FILE* f) {
	C_Vec4数组节点* node = new C_Vec4数组节点(ctx);
	return node;
}

void f_node_保存Vec4数组节点(C_节点基类* n, FILE* f) {
	C_Vec4数组节点* node = dynamic_cast<C_Vec4数组节点*>(n);
}




C_坐标构建平面节点::C_坐标构建平面节点(S_设备环境& ctx) : C_节点基类(DEF_坐标构建平面变量节点) {
	m_Name = L"平面";
	m_Ctx = ctx;

	C_插座基类* socket;
	DEF_创建Vec3_1D插座_I(L"点");

	DEF_创建Vec4_1D插座_O(L"平面");

}

C_坐标构建平面节点::~C_坐标构建平面节点() {
}

bool C_坐标构建平面节点::f_update() {
	auto* socket1 = f_get输入插座(1);
	auto* outSocket1 = f_get输出插座(1);

	auto* point = DEF_Vec3插座_1D数据(socket1);
	auto* plane = DEF_Vec4插座_1D数据(outSocket1);

	f_mat_平面构建(point, plane);
	
	return false;
}

std::string C_坐标构建平面节点::f_编译(C_节点基类* rn, std::string& 声明, std::vector<std::string>& 定义, std::string& 释放) {
	m_Code = "";
	m_ReleaseCode = "";
	//C_节点树* rt = f_getThis节点树();
	std::string name = f_WStringToString(m_Name);

	C_插座基类* socket1 = f_get输入插座(1);


	m_Code += DEF_S(S_Vec4Array* )" " + name + ";\n";

	m_Code += "{\n";
	m_Code += socket1->f_构建变量代码(0);
	m_Code += name + " = " + f_代码构建_创建Array(E_值类型::e_Type_Vec4_1D, "1") + ";\n";
	m_Code += DEF_S(f_mat_平面构建)"(" + socket1->f_getCode(0) + ", " + name + ");\n";
	m_Code += m_ReleaseCode;
	m_Code += "}\n";

	f_get输出插座(1)->f_setCode(name);
	if (m_区域父节点) {
		m_区域父节点->m_Code += m_Code;
		m_区域父节点->m_ReleaseCode += f_代码构建_销毁数组(name);
		return "";
	}
	释放 += f_代码构建_销毁数组(name);
	return m_Code;
}

void C_坐标构建平面节点::f_读取(FILE* f) {
	C_节点基类::f_读取(f);
}

void C_坐标构建平面节点::f_写入(FILE* f) {
	C_节点基类::f_写入(f);
}

C_节点基类* f_node_创建坐标构建平面节点(S_设备环境& ctx, C_节点树* 子节点树) {
	return new C_坐标构建平面节点(ctx);
}

C_节点基类* f_node_加载坐标构建平面节点(S_设备环境& ctx, FILE* f) {
	C_坐标构建平面节点* node = new C_坐标构建平面节点(ctx);
	return node;
}
void f_node_保存坐标构建平面节点(C_节点基类* n, FILE* f) {
	C_坐标构建平面节点* node = dynamic_cast<C_坐标构建平面节点*>(n);
}



C_线段数据节点::C_线段数据节点(S_设备环境& ctx) : C_节点基类(DEF_线段变量节点) {
	m_Name = L"线段";
	m_Ctx = ctx;

	C_插座基类* socket;
	DEF_创建Vec3插座_v1_I(L"开始点");
	DEF_创建Vec3插座_v1_I(L"结束点");

	DEF_创建线段插座_O(L"线段");

	DEF_Vec3插座数据(f_get输入插座(1)) = { 0,0,0 };
	DEF_Vec3插座数据(f_get输入插座(2)) = { 0,0,0 };
}

C_线段数据节点::~C_线段数据节点() {

}

bool C_线段数据节点::f_update() {
	auto& line_s = DEF_Vec3插座数据(f_get输入插座(1));
	auto& line_e = DEF_Vec3插座数据(f_get输入插座(2));

	auto& outLine = *DEF_线段插座数据(f_get输出插座(1), 0);

	outLine.begin = line_s;
	outLine.end = line_e;

	return false;
}

void C_线段数据节点::f_读取(FILE* f) {
	C_节点基类::f_读取(f);
}

void C_线段数据节点::f_写入(FILE* f) {
	C_节点基类::f_写入(f);
}



C_节点基类* f_node_创建线段数据节点(S_设备环境& ctx, C_节点树* 子节点树) {
	return new C_线段数据节点(ctx);
}

C_节点基类* f_node_加载线段数据节点(S_设备环境& ctx, FILE* f) {
	C_线段数据节点* node = new C_线段数据节点(ctx);

	return node;
}

void f_node_保存线段数据节点(C_节点基类* n, FILE* f) {
	C_线段数据节点* node = dynamic_cast<C_线段数据节点*>(n);
}





C_观察矩阵构建节点::C_观察矩阵构建节点(S_设备环境& ctx) : C_节点基类(DEF_观察矩阵构建节点) {
	m_Name = L"观察矩阵";
	m_Ctx = ctx;

	C_插座基类* socket;
	DEF_创建Vec3插座_I(L"视点", nullptr);
	DEF_创建Vec3插座_I(L"目标", nullptr);
	DEF_创建Vec3插座_I(L"上方向", nullptr);

	DEF_创建Mat4X4插座_O(L"矩阵");

	DEF_Vec3插座数据(f_get输入插座(3)) = { 0,1,0 };

	m_翻转 = f_alloc_BoolProp(nullptr, L"逆矩阵");
	m_翻转.m_私有 = true;

}

C_观察矩阵构建节点::~C_观察矩阵构建节点() {
	f_prop_Release(m_翻转);
}

bool C_观察矩阵构建节点::f_update() {
	auto& 视点 = DEF_Vec3插座数据(f_get输入插座(1));
	auto& 目标 = DEF_Vec3插座数据(f_get输入插座(2));
	auto& 上方向 = DEF_Vec3插座数据(f_get输入插座(3));

	auto& mat = *DEF_Mat4X4插座数据(f_get输出插座(1));

	mat = f_mat44_LookAtMatrix(视点, 目标, 上方向);
	
	if (f_prop_Bool(m_翻转)) {
		mat = f_mat44_Inverse(mat);
	}

	return false;
}

std::string C_观察矩阵构建节点::f_编译(C_节点基类* rn, std::string& 声明, std::vector<std::string>& 定义, std::string& 释放) {
	return std::string();
}

void C_观察矩阵构建节点::f_读取(FILE* f) {
	C_节点基类::f_读取(f);
	f_prop_Load(m_翻转, f);
}

void C_观察矩阵构建节点::f_写入(FILE* f) {
	C_节点基类::f_写入(f);
	f_prop_Save(m_翻转, f);
}


C_节点基类* f_node_创建观察矩阵构建节点(S_设备环境& ctx, C_节点树* 子节点树) {
	return new C_观察矩阵构建节点(ctx);
}

C_节点基类* f_node_加载观察矩阵构建节点(S_设备环境& ctx, FILE* f) {
	C_观察矩阵构建节点* node = new C_观察矩阵构建节点(ctx);
	return node;
}

void f_node_保存观察矩阵构建节点(C_节点基类* n, FILE* f) {
	C_观察矩阵构建节点* node = dynamic_cast<C_观察矩阵构建节点*>(n);
}




C_线段1D数据节点::C_线段1D数据节点(S_设备环境& ctx) : C_节点基类(DEF_线段1D变量节点)  {
	m_Name = L"[线段]";
	m_Ctx = ctx;

	C_插座基类* socket;
	DEF_创建Vec3_Array1D插座_I(L"开始点");
	DEF_创建Vec3_Array1D插座_I(L"结束点");

	DEF_创建线段_1D插座_O(L"线段");

	m_组合类型 = f_alloc_EnumProp(nullptr, { {L"无", ""}, {L"+", ""}, {L"-", ""}, {L"序列", ""} }, L"合成类型");
	m_组合类型.m_私有 = true;

}

C_线段1D数据节点::~C_线段1D数据节点(){

}

bool C_线段1D数据节点::f_update() {
	auto& inData1 = *DEF_Vec3_Array1D插座数据(f_get输入插座(1), 0);
	auto& inData2 = *DEF_Vec3_Array1D插座数据(f_get输入插座(2), 0);
	auto& outData = *DEF_线段_1D插座数据(f_get输出插座(1), 0);

	uint32 num = inData1.size();
	
	auto* inData1_ptr = inData1.data();
	auto* inData2_ptr = inData2.data();

	if (f_prop_enum(m_组合类型) == 0) {
		if (num >= 2) {
			num /= 2;

			outData.resize(num);
			auto* outData_ptr = outData.data();

			for (uint32 i = 0; i < num; ++i) {
				outData_ptr[i].begin = inData1_ptr[i*2];
				outData_ptr[i].end = inData1_ptr[i*2+1];
			}

			return false;
		}
	}

	outData.resize(num);
	auto* outData_ptr = outData.data();

	if (inData2.size() >= inData1.size()) {
		switch (f_prop_enum(m_组合类型))
		{
		case 0: {
			for (uint32 i = 0; i < num; ++i) {
				outData_ptr[i].begin = inData1_ptr[i];
				outData_ptr[i].end = inData2_ptr[i];
			}
			break;
		}

		case 1: {
			for (uint32 i = 0; i < num; ++i) {
				outData_ptr[i].begin = inData1_ptr[i];
				outData_ptr[i].end = inData1_ptr[i] + inData2_ptr[i];
			}
			break;
		}

		case 2: {
			for (uint32 i = 0; i < num; ++i) {
				outData_ptr[i].begin = inData1_ptr[i];
				outData_ptr[i].end = inData1_ptr[i] - inData2_ptr[i];
			}
			break;
		}

		case 3: {
			
			
			break;
		}

		default:
			break;
		}
	}
	else {
		switch (f_prop_enum(m_组合类型))
		{
		case 0: {
			for (uint32 i = 0; i < num; ++i) {
				outData_ptr[i].begin = inData1_ptr[i];
				outData_ptr[i].end = inData2_ptr[0];
			}
			break;
		}

		case 1: {
			for (uint32 i = 0; i < num; ++i) {
				outData_ptr[i].begin = inData1_ptr[i];
				outData_ptr[i].end = inData1_ptr[i] + inData2_ptr[0];
			}
			break;
		}

		case 2: {
			for (uint32 i = 0; i < num; ++i) {
				outData_ptr[i].begin = inData1_ptr[i];
				outData_ptr[i].end = inData1_ptr[i] - inData2_ptr[0];
			}
			break;
		}

		default:
			break;
		}
	}

	return false;
}

void C_线段1D数据节点::f_读取(FILE* f) {
	C_节点基类::f_读取(f);
	f_prop_Load(m_组合类型, f);
}

void C_线段1D数据节点::f_写入(FILE* f) {
	C_节点基类::f_写入(f);
	f_prop_Save(m_组合类型, f);
}

C_节点基类* f_node_创建线段1D变量节点(S_设备环境& ctx, C_节点树* 子节点树) {
	return new C_线段1D数据节点(ctx);
}

C_节点基类* f_node_加载线段1D数据节点(S_设备环境& ctx, FILE* f) {
	C_线段1D数据节点* node = new C_线段1D数据节点(ctx);

	return node;
}

void f_node_保存线段1D数据节点(C_节点基类* n, FILE* f) {
	C_线段1D数据节点* node = dynamic_cast<C_线段1D数据节点*>(n);
}





C_数组变量节点::C_数组变量节点(S_设备环境& ctx) : C_节点基类(DEF_数组变量节点) {
	m_Name = L"数组";
	m_Ctx = ctx;

	C_插座基类* socket;
	DEF_创建UI32插座_I(L"数量");
	DEF_创建数组插座_O(L"变量");

	m_元素类型 = f_alloc_EnumProp(nullptr, {
		{L"[Bool]", ""},
		{L"[I32]", ""},
		{L"[UI32]", ""},
		{L"[F32]", ""},

		{L"[vec2]", ""},
		{L"[vec3]", ""},
		{L"[vec4]", ""},

		{L"[ivec2]", ""},
		{L"[ivec3]", ""},
		{L"[ivec3]", ""},

		{L"[uvec2]", ""},
		{L"[uvec3]", ""},
		{L"[uvec3]", ""},

		{L"[face]", ""},
		{L"[元素]", ""},
		{L"[poly]", ""},
		{L"[edge]", ""},

		}, L"类型");
	m_元素类型.m_私有 = true;


}

C_数组变量节点::~C_数组变量节点() {
	f_prop_Release(m_元素类型);
}

bool C_数组变量节点::f_update() {
	return false;
}

std::string C_数组变量节点::DEF_节点编译函数{
	m_Code = "";
	m_ReleaseCode = "";
	C_插座基类* socket1 = f_get输入插座(1);
	auto name = f_getName();


	E_值类型 type;
	switch (f_prop_enum(m_元素类型)) {
		case 0: type = E_值类型::e_Type_Bool_1D;       m_Code += DEF_S(S_BoolArray*); break;
		case 1: type = E_值类型::e_Type_I32_1D;        m_Code += DEF_S(S_I32Array*); break;
		case 2: type = E_值类型::e_Type_UI32_1D;       m_Code += DEF_S(S_UI32Array*); break;
		case 3: type = E_值类型::e_Type_F32_1D;        m_Code += DEF_S(S_F32Array*);break;

		case 4: type = E_值类型::e_Type_Vec2_1D;       m_Code += DEF_S(S_Vec2Array*);break;
		case 5: type = E_值类型::e_Type_Vec3_1D;       m_Code += DEF_S(S_Vec3Array*);break;
		case 6: type = E_值类型::e_Type_Vec4_1D;       m_Code += DEF_S(S_Vec4Array*);break;

		case 7: type = E_值类型::e_Type_iVec2_1D;      m_Code += DEF_S(S_iVec2Array*);break;
		case 8: type = E_值类型::e_Type_iVec3_1D;      m_Code += DEF_S(S_iVec3Array*);break;
		case 9: type = E_值类型::e_Type_iVec3_1D;      m_Code += DEF_S(S_iVec3Array*);break;

		case 10: type = E_值类型::e_Type_uVec2_1D;     m_Code += DEF_S(S_uVec2Array*);break;
		case 11: type = E_值类型::e_Type_uVec3_1D;     m_Code += DEF_S(S_uVec2Array*);break;
		case 12: type = E_值类型::e_Type_uVec3_1D;     m_Code += DEF_S(S_uVec2Array*);break;

		case 13: type = E_值类型::e_Type_多边形面1D;   m_Code += DEF_S(S_多边形元素*);break;
		case 14: type = E_值类型::e_Type_多边形元素;   m_Code += DEF_S(S_多边形元素*);break;
		case 15: type = E_值类型::e_Type_多边形元素1D; m_Code += DEF_S(S_多边形元素Array*); break;

		case 16: type = E_值类型::e_Type_多边形边1D;   m_Code += DEF_S(S_边Array*);break;
	default:
		break;
	}


	m_Code += " " + name + ";\n";
	m_Code += "{\n";

	auto socetOut1 = f_get输出插座(1);
	switch (type) {
		case E_值类型::e_Type_Bool_1D:
		case E_值类型::e_Type_I32_1D:
		case E_值类型::e_Type_UI32_1D:
		case E_值类型::e_Type_F32_1D:
		case E_值类型::e_Type_Vec2_1D:
		case E_值类型::e_Type_Vec3_1D:
		case E_值类型::e_Type_Vec4_1D:
		case E_值类型::e_Type_iVec2_1D:
		case E_值类型::e_Type_iVec3_1D:
		case E_值类型::e_Type_多边形面1D:
		case E_值类型::e_Type_多边形元素:
		case E_值类型::e_Type_多边形元素1D:
		case E_值类型::e_Type_多边形边1D:
			f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输出, 1, type);
			break;
	default:
		break;
	}

	m_Code += name + " = " + f_代码构建_创建Array(type, "0") + ";\n";
	m_Code += m_ReleaseCode;
	m_Code += "}\n";

	socetOut1 = f_get输出插座(1);
	f_get输出插座(1)->f_setCode(name);

	if (m_区域父节点) {
		m_区域父节点->m_Code += m_Code;
		m_区域父节点->m_ReleaseCode += f_代码构建_销毁数组(name);
		return "";
	}

	释放 += f_代码构建_销毁数组(name);
	return m_Code;
}

void C_数组变量节点::f_读取(FILE* f) {
	C_节点基类::f_读取(f);
	f_prop_Load(m_元素类型, f);
}

void C_数组变量节点::f_写入(FILE* f) {
	C_节点基类::f_写入(f);
	f_prop_Save(m_元素类型, f);
}

C_节点基类* f_node_创建数组变量节点(S_设备环境& ctx, C_节点树* 子节点树) {
	return new C_数组变量节点(ctx);
}

C_节点基类* f_node_加载数组变量节点(S_设备环境& ctx, FILE* f) {
	C_数组变量节点* node = new C_数组变量节点(ctx);
	return node;
}

void f_node_保存数组变量节点(C_节点基类* n, FILE* f) {
	C_数组变量节点* node = dynamic_cast<C_数组变量节点*>(n);
}





C_数组添加元素节点::C_数组添加元素节点(S_设备环境& ctx) : C_节点基类(DEF_添加数组元素节点) {
	m_Name = L"添加数组元素";
	m_Ctx = ctx;

	C_插座基类* socket;
	DEF_创建数组插座_I(L"数组");
	DEF_创建引用插座_I(L"元素");
	DEF_创建UI32插座_I(L"索引");

	DEF_创建数组插座_O(L"元素");

	f_get输入插座(2)->f_set多输入();


	m_添加方式 = f_alloc_EnumProp(nullptr, {
		{L"结尾", ""},
		{L"插入", ""},
		{L"开头", ""},
		}, L"类型");
	m_添加方式.m_私有 = true;
}

C_数组添加元素节点::~C_数组添加元素节点() {
	f_prop_Release(m_添加方式);
}

bool C_数组添加元素节点::f_update() {
	C_插座基类* socket1 = f_get输入插座(1);
	C_插座基类* socket2 = f_get输入插座(2);

	if (socket2->f_isLink() == false) {
		f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输入, 2, E_值类型::e_插座Type_引用数据);
	}

	if (socket1->f_isLink()) {
		f_su_插座类型切换到连入的插座类型(this, E_插座方向::e_插座Type_输入, 1);
		socket1 = f_get输入插座(1);
		socket2 = f_get输入插座(2);
		uint32 num = socket1->f_getLinkNum();


		C_插座基类* socket3 = f_get输入插座(3);
		f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输出, 1, socket1->m_Type);

		for (uint32 i = 0; i < num; ++i) {
			void* data = socket1->f_getData(i);

			//f_core_array_push_back(a, (uint8*)&data);
		}
	}
	else {
		f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输入, 1, E_值类型::e_Type_Array);
		f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输出, 1, E_值类型::e_Type_Array);
	}
	return false;
}

std::string C_数组添加元素节点::DEF_节点编译函数{
	m_Code = "";
	m_ReleaseCode = "";
	C_插座基类* socket1 = f_get输入插座(1);
	C_插座基类* socket2 = f_get输入插座(2);
	/*S_边* edge = new S_边();
	auto ea = edge;
	ea->edge.push_back({ 1,2 });
	S_Array* a = f_core_array_new(0, 4);
	f_core_array_change_elt_size(a, sizeof(S_边**));
	f_core_array_push_back(a, (const uint8*)&ea);
	S_边* eb = *(S_边**)f_core_array_at(a, 0);*/
	uint32 num = socket2->f_getLinkNum();

	
	if (socket2->f_isLink() == false) {
		f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输入, 2, E_值类型::e_插座Type_引用数据);
	}

	if (socket1->f_isLink()) {
		f_su_插座类型切换到连入的插座类型(this, E_插座方向::e_插座Type_输入, 1);
		socket1 = f_get输入插座(1);
		socket2 = f_get输入插座(2);

		
		C_插座基类* socket3 = f_get输入插座(3);

		
		m_Code += "{\n";

		f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输出, 1, socket1->m_Type);

		std::string 元素大小;
		switch (socket1->m_Type) {
			case E_值类型::e_Type_Bool_1D: 元素大小 += DEF_S(sizeof(bool));
				f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输入, 2, E_值类型::e_Type_Bool);
				break;
			case E_值类型::e_Type_I8_1D: 元素大小 += DEF_S(sizeof(int8));
				f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输入, 2, E_值类型::e_Type_I8);
				break;
			case E_值类型::e_Type_I32_1D: 元素大小 += DEF_S(sizeof(int32));
				f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输入, 2, E_值类型::e_Type_I32);
				break;
			case E_值类型::e_Type_UI32_1D: 元素大小 += DEF_S(sizeof(uint32));
				f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输入, 2, E_值类型::e_Type_UI32);
				break;
			case E_值类型::e_Type_F32_1D: 元素大小 += "sizeof(float32)";
				f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输入, 2, E_值类型::e_Type_F32);
				break;
			case E_值类型::e_Type_Vec2_1D: 元素大小 += "sizeof(vec2)";
				f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输入, 2, E_值类型::e_Type_Vec2);
				break;
			//case E_值类型::e_Type_Vec2_2D: 元素大小 += DEF_S(sizeof(S_Vec2Array*));
			//	f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输入, 2, E_值类型::e_Type_Vec2_1D);
			//	break;
			case E_值类型::e_Type_Vec3_1D: 元素大小 += "sizeof(vec3)";
				f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输入, 2, E_值类型::e_Type_Vec3);
				break;
			//case E_值类型::e_Type_Vec3_2D: 元素大小 += DEF_S(sizeof(S_Vec3Array*));
			//	f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输入, 2, E_值类型::e_Type_Vec3_1D);
			//	break;
			case E_值类型::e_Type_Vec4_1D: 元素大小 += "sizeof(vec4)";
				f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输入, 2, E_值类型::e_Type_Vec4);
				break;
			case E_值类型::e_Type_iVec2_1D: 元素大小 += DEF_S(sizeof(ivec2));
				f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输入, 2, E_值类型::e_Type_iVec2);
				break;
			case E_值类型::e_Type_iVec3_1D: 元素大小 += DEF_S(sizeof(ivec3));
				f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输入, 2, E_值类型::e_Type_iVec3);
				break;
			case E_值类型::e_Type_uVec2_1D: 元素大小 += DEF_S(sizeof(uvec2));
				f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输入, 2, E_值类型::e_Type_uVec2);
				break;
			case E_值类型::e_Type_UI32_2D: 元素大小 += DEF_S(sizeof(S_UI32Array*));
				f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输入, 2, E_值类型::e_Type_UI32_1D);
				break;
			case E_值类型::e_Type_多边形边1D: 元素大小 += DEF_S(sizeof(S_边*));
				f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输入, 2, E_值类型::e_Type_多边形边);
				break;
			case E_值类型::e_Type_多边形元素 : 元素大小 += DEF_S(sizeof(S_面*));
				f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输入, 2, E_值类型::e_Type_多边形面);
				break;
			case E_值类型::e_Type_多边形元素1D: 元素大小 += DEF_S(sizeof(S_多边形元素*));
				f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输入, 2, E_值类型::e_Type_多边形元素);
				break;

			default:
				f_su_插座类型切换到连入的插座类型(this, E_插座方向::e_插座Type_输入, 2);
				switch (socket2->m_Type) {
					case E_值类型::e_Type_Bool_1D: 元素大小 += DEF_S(sizeof(bool));
						f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输出, 1, E_值类型::e_Type_Bool_1D);
						break;
					case E_值类型::e_Type_I8: 元素大小 += DEF_S(sizeof(int8));
						f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输出, 1, E_值类型::e_Type_I8_1D);
						break;
					case E_值类型::e_Type_I32: 元素大小 += DEF_S(sizeof(int32));
						f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输出, 1, E_值类型::e_Type_I32_1D);
						break;
					case E_值类型::e_Type_UI32: 元素大小 += DEF_S(sizeof(uint32));
						f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输出, 1, E_值类型::e_Type_UI32_1D);
						break;
					case E_值类型::e_Type_F32: 元素大小 += "sizeof(float32)";
						f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输出, 1, E_值类型::e_Type_F32_1D);
						break;
					case E_值类型::e_Type_Vec2: 元素大小 += "sizeof(vec2)";
						f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输出, 1, E_值类型::e_Type_Vec2_1D);
						break;
					case E_值类型::e_Type_Vec3: 元素大小 += "sizeof(vec3)";
						f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输出, 1, E_值类型::e_Type_Vec3_1D);
						break;
					case E_值类型::e_Type_Vec4: 元素大小 += "sizeof(vec4)";
						f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输出, 1, E_值类型::e_Type_Vec4_1D);
						break;
					case E_值类型::e_Type_iVec2: 元素大小 += DEF_S(sizeof(ivec2));
						f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输出, 1, E_值类型::e_Type_iVec2_1D);
						break;
					case E_值类型::e_Type_iVec3: 元素大小 += DEF_S(sizeof(ivec3));
						f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输出, 1, E_值类型::e_Type_iVec3_1D);
						break;
					case E_值类型::e_Type_uVec2: 元素大小 += DEF_S(sizeof(uvec2));
						f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输出, 1, E_值类型::e_Type_uVec2_1D);
						break;
					case E_值类型::e_Type_多边形边: 元素大小 += DEF_S(sizeof(S_边*));
						f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输出, 1, E_值类型::e_Type_多边形边1D);
						break;
					case E_值类型::e_Type_多边形面: 元素大小 += DEF_S(sizeof(S_面*));
						f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输出, 1, E_值类型::e_Type_多边形元素);
						break;
					default:
						std::cout<<"error:数组添加元素输入不支持的类型"<<std::endl;
						return "";
				}
				break;
		}
		

		auto* rt = f_getThis节点树();
		socket1 = f_get输入插座(1);
		socket2 = f_get输入插座(2);

		m_Code += socket1->f_构建变量代码(0);
		m_Code += socket3->f_构建变量代码(0);


		m_Code += DEF_S(f_core_array_change_elt_size)"((S_Array*)" + socket1->f_getCode(0) + ", " + 元素大小 + ");\n";
		for (uint32 i = 0; i < num; ++i) {
			m_Code += socket2->f_构建变量代码(i);


			m_Code += "switch(" + f_代码构建_属性变量(m_添加方式, rt) + "){\n";
			m_Code += "case 0: " DEF_S(f_core_array_push_back) "((S_Array*)" + socket1->f_getCode(i) + ", ((const uint8*)&" + socket2->f_getCode(i) + ")); break; \n";
			m_Code += "case 1: " DEF_S(f_core_array_insert_elt)"((S_Array*)" + socket1->f_getCode(i) + ", " + socket3->f_getCode(i) + ", ((const uint8*)&" + socket2->f_getCode(i) + ") ); break; \n";
			//m_Code += "case 2: bitSize = sizeof(float32); break;\n";
			m_Code += "}\n";
		}


		m_Code += m_ReleaseCode;
		m_Code += "}\n";

		f_get输出插座(1)->f_setCode(socket1->f_getCode(0));
		if (m_区域父节点) {
			m_区域父节点->m_Code += m_Code;
			return "";
		}
	}
	else {
		f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输入, 1, E_值类型::e_Type_Array);
		f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输出, 1, E_值类型::e_Type_Array);
		f_get输出插座(1)->f_setCode("");
	}

	return m_Code;
}

void C_数组添加元素节点::f_读取(FILE* f) {
	C_节点基类::f_读取(f);
	f_prop_Load(m_添加方式, f);
}

void C_数组添加元素节点::f_写入(FILE* f) {
	C_节点基类::f_写入(f);
	f_prop_Save(m_添加方式, f);
}

C_节点基类* f_node_创建数组添加元素节点(S_设备环境& ctx, C_节点树* 子节点树) {
	return new C_数组添加元素节点(ctx);
}

C_节点基类* f_node_加载数组添加元素节点(S_设备环境& ctx, FILE* f) {
	C_数组添加元素节点* node = new C_数组添加元素节点(ctx);
	return node;
}

void f_node_保存数组添加元素节点(C_节点基类* n, FILE* f) {
	C_数组添加元素节点* node = dynamic_cast<C_数组添加元素节点*>(n);
}





C_取数组属性节点::C_取数组属性节点(S_设备环境& ctx) : C_节点基类(DEF_取数组属性节点) {
	m_Name = L"数组属性";
	m_Ctx = ctx;

	C_插座基类* socket;
	DEF_创建数组插座_I(L"数组");
	DEF_创建UI32插座_O(L"数量");
	DEF_创建UI32插座_O(L"元素大小");
}

C_取数组属性节点::~C_取数组属性节点() {
}

bool C_取数组属性节点::f_update() {
	return false;
}

std::string C_取数组属性节点::DEF_节点编译函数{
	m_Code = "";
	m_ReleaseCode = "";

	std::string name = f_getName();
	std::string 元素数量 = name + "_元素数量";
	std::string 元素大小 = name + "_元素大小";
	m_Code += "uint32 " + 元素数量 + " = 0;";
	m_Code += "uint32 " + 元素大小 + " = 0;";
	
	auto* socket1 = f_get输入插座(1);
	if (socket1->f_isLink()) {
		auto* socket2 = f_get输入插座(1);

		m_Code += socket1->f_构建变量代码(0) + "\n";
		m_Code += socket2->f_构建变量代码(0) + "\n";

		m_Code += 元素数量 + " = " + f_代码构建_Array数组数量(socket1->f_getCode(0)) + ";\n";
		m_Code += 元素大小 + " = " + f_代码构建_Array元素大小(socket2->f_getCode(0)) + ";\n";
	}

	f_get输出插座(1)->f_setCode(元素数量);
	f_get输出插座(2)->f_setCode(元素大小);

	m_Code += m_ReleaseCode;
	if (m_区域父节点) {
		m_区域父节点->m_Code += m_Code;
		return "";
	}

	return m_Code;
}

void C_取数组属性节点::f_读取(FILE* f) {
	C_节点基类::f_读取(f);

	auto 文件块 = f_file_读取文件块(f);
	if (文件块.m_块类型 == E_节点工程文件块类型::e_工程文件块_节点实例属性) {
		const uint8* 下一次读取数据指针 = 文件块.m_data;
		switch (文件块.m_版本号) {
			case 0 << 32 | 1: {
				break;
			}
		}

		//f_prop_Load(m_反向, 下一次读取数据指针);
	}
	free(文件块.m_data);
}

void C_取数组属性节点::f_写入(FILE* f) {
	C_节点基类::f_写入(f);
	auto 文件块 = f_file_构建文件块信息(E_节点工程文件块类型::e_工程文件块_节点实例属性, S_节点数据::g_文件版本号);

	S_UI8Array* 块 = (S_UI8Array*)f_core_array_new(0, sizeof(uint8));
	//f_prop_Save(m_反向, 块);

	文件块.m_data = 块->ptr_userData;
	文件块.m_字节数 = 块->count;
	f_file_保存文件块(f, 文件块);
	f_core_array_free((S_Array*)块);
}

C_节点基类* f_node_创建取数组属性节点(S_设备环境& ctx, C_节点树* 子节点树) {
	return new C_取数组属性节点(ctx);
}

C_节点基类* f_node_加载取数组属性节点(S_设备环境& ctx, FILE* f) {
	C_取数组属性节点* node = new C_取数组属性节点(ctx);
	return node;
}

void f_node_保存取数组属性节点(C_节点基类* n, FILE* f) {
	C_取数组属性节点* node = dynamic_cast<C_取数组属性节点*>(n);
}




C_取数组元素节点::C_取数组元素节点(S_设备环境& ctx) : C_节点基类(DEF_取数组元素节点) {
	m_Name = L"取数组元素";
	m_Ctx = ctx;

	C_插座基类* socket;
	DEF_创建数组插座_I(L"数组");
	DEF_创建UI32插座_I(L"索引");
	DEF_创建UI32插座_O(L"元素");


	m_位置索引 = f_alloc_EnumProp(nullptr, {
		{L"索引", ""},
		{L"头", ""},
		{L"尾", ""},
							  }, L"类型");
	m_位置索引.m_私有 = true;

}

C_取数组元素节点::~C_取数组元素节点() {
	f_prop_Release(m_位置索引);
}

bool C_取数组元素节点::f_update() {
	f_su_插座类型切换到连入的插座类型(this, E_插座方向::e_插座Type_输入, 1);
	auto* socket1 = f_get输入插座(1);

	uint32 index = DEF_UI32插座数据(f_get输入插座(2));

	S_Array* data = (S_Array*)socket1->f_getData(0);
	if (data->count > index) {
		switch (socket1->f_get接入的数据类型()) {
			case E_值类型::e_Type_F32_1D: {
				break;
			}
			case E_值类型::e_Type_Object_1D: {
				f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输出, 1, E_值类型::e_Type_Object);

				f_get输出插座(1)->f_setData(((S_物体**)(data->ptr_userData))[index]);
				break;
			}
			default:
				break;
		}
	}

	return false;
}

std::string C_取数组元素节点::DEF_节点编译函数{
	m_Code = "";
	m_ReleaseCode = "";
	std::string name = f_getName();

	
	
	auto* socket1 = f_get输入插座(1);
	auto* socket2 = f_get输入插座(2);

	if (!socket1->f_isLink() && !socket1->f_isLink()) {
		f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输入, 1, E_值类型::e_Type_Array);
		return "";
	}

	f_su_插座类型切换到连入的插座类型(this, E_插座方向::e_插座Type_输入, 1, E_值类型::e_Type_Array);
	socket1 = f_get输入插座(1);

	if (f_代码构建_数组指针(socket1) == false) {
		f_get输出插座(1)->f_setCode("");
		std::cout << "error 取数组元素节点:" << name << "节点输入数据不是数组" << std::endl;
		m_编译成功 = false;
		return "";
	}

	
	
		
	m_Code += socket1->f_构建变量代码(0);
	m_Code += socket2->f_构建变量代码(0);

	auto 元素 = socket1->f_getCode(0);
	auto index = socket2->f_getCode(0);
	auto indexName = name + "_index";

	m_Code += "uint32 " + indexName + " = " + socket2->f_getCode(0) + ";\n";
		

	std::string 类型;
	switch (socket1->m_Type) {
		case E_值类型::e_Type_I8_1D:
			f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输出, 1, E_值类型::e_Type_I8);
			m_Code += "auto& " + name + " = ";
			类型 = DEF_S(int8)" " + name + "tmp_reference{};\n";
			break;
		case E_值类型::e_Type_F32_1D:
			f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输出, 1, E_值类型::e_Type_F32);
			m_Code += "auto& " + name + " = ";
			类型 = DEF_S(float32)" " + name + "tmp_reference{};\n";
			break;
		case E_值类型::e_Type_I32_1D:
			f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输出, 1, E_值类型::e_Type_I32);
			m_Code += "auto& " + name + " = ";
			类型 = DEF_S(int32)" " + name + "tmp_reference{};\n";
			break;
		case E_值类型::e_Type_Vec2_1D:
			f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输出, 1, E_值类型::e_Type_Vec2);
			m_Code += "auto& " + name + " = ";
			类型 = DEF_S(vec2)" " + name + "tmp_reference{};\n";
			break;

		case E_值类型::e_Type_Vec3_1D:
			f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输出, 1, E_值类型::e_Type_Vec3);
			m_Code += "auto& " + name + " = ";
			类型 = DEF_S(vec3)" " + name + "tmp_reference{};\n";
			break;
		case E_值类型::e_Type_Vec3_2D:
			f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输出, 1, E_值类型::e_Type_Vec3_1D);
			m_Code += "auto& " + name + " = ";
			类型 = "static S_Vec3Array " + name + "static_temp{};\n";
			类型 += DEF_S(S_Vec3Array*)" " + name + "tmp_reference = &" + name + "static_temp;\n";
			break;

		case E_值类型::e_Type_Vec4_1D:
			f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输出, 1, E_值类型::e_Type_Vec4);
			m_Code += "auto& " + name + " = ";
			类型 = DEF_S(vec4)" " + name + "tmp_reference{};\n";
			break;
		case E_值类型::e_Type_iVec2_1D:
			f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输出, 1, E_值类型::e_Type_iVec2);
			m_Code += "auto& " + name + " = ";
			类型 = DEF_S(ivec2)" " + name + "tmp_reference{};\n";
			break;

		case E_值类型::e_Type_iVec3_1D:
			f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输出, 1, E_值类型::e_Type_iVec3);
			m_Code += "auto& " + name + " = ";
			类型 = DEF_S(ivec3)" " + name + "tmp_reference{};\n";
			break;
		case E_值类型::e_Type_iVec3_2D:
			f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输出, 1, E_值类型::e_Type_iVec3_1D);
			
			m_Code += "auto& " + name + " = ";
			类型 = "static S_iVec3Array " + name + "static_temp{};\n";
			类型 += DEF_S(S_iVec3Array*)" " + name + "tmp_reference = &" + name + "static_temp;\n";
			break;

		case E_值类型::e_Type_uVec2_1D:
			f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输出, 1, E_值类型::e_Type_uVec2);
			m_Code += "auto& " + name + " = ";
			类型 = DEF_S(vec2)" " + name + "tmp_reference{};\n";
			break;
		case E_值类型::e_Type_多边形边1D:
			f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输出, 1, E_值类型::e_Type_多边形边);
			m_Code += "auto* " + name + " = ";
			类型 = DEF_S(S_边*)" " + name + "tmp_reference{};\n";
			break;

		case E_值类型::e_Type_UI32_2D:
			f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输出, 1, E_值类型::e_Type_UI32_1D);
			m_Code += "auto& " + name + " = ";
			类型 = DEF_S(S_UI32Array*)" " + name + "tmp_reference{};\n";
			break;
		//case E_值类型::e_Type_Array:
		//	break;
		case E_值类型::e_Type_纹理1D:
			//static S_纹理
			f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输出, 1, E_值类型::e_Type_纹理);
			m_Code += "auto& " + name + " = ";
			类型 = "static S_纹理* " + name + "static_temp = (S_纹理*)" + f_整数值转字符串((uint64)S_光追后端::G纹理[0].m_Ptr) + ";\n";
			类型 += DEF_S(S_纹理*)" " + name + "tmp_reference = " + name + "static_temp;\n";
			break;
		default:
			std::cout<<"error :" << name << "节点输入数据不是数组" << std::endl;
			return "";
			break;
	}
		
	m_Code = 类型 + m_Code;

	//switch (f_prop_enum(m_位置索引)) {
	//	case 0: {
	//		break;
	//	}
	//	case 1: {
	//		break;
	//	}
	//	case 2: {
	//		break;
	//	}
	//	default:
	//		break;
	//}
	m_Code += indexName + " >= " + 元素 + "->count ? ";
	m_Code += name + "tmp_reference" + " : (" + 元素 + "->ptr_userData)[" + indexName + "];\n";
	m_Code += m_ReleaseCode;

	f_get输出插座(1)->f_setCode(name);
	
	
	

	if (m_区域父节点) {
		m_区域父节点->m_Code += m_Code;
		return "";
	}

	return m_Code;
}

void C_取数组元素节点::f_读取(FILE* f) {
	C_节点基类::f_读取(f);

	auto 文件块 = f_file_读取文件块(f);
	if (文件块.m_块类型 == E_节点工程文件块类型::e_工程文件块_节点实例属性) {
		const uint8* 下一次读取数据指针 = 文件块.m_data;
		switch (文件块.m_版本号) {
			case 0 << 32 | 1: {
				break;
			}
		}
		下一次读取数据指针 = f_prop_Load(m_位置索引, 下一次读取数据指针);
	}
	free(文件块.m_data);
}

void C_取数组元素节点::f_写入(FILE* f) {
	C_节点基类::f_写入(f);
	auto 文件块 = f_file_构建文件块信息(E_节点工程文件块类型::e_工程文件块_节点实例属性, S_节点数据::g_文件版本号);
	S_UI8Array* 块 = (S_UI8Array*)f_core_array_new(0, sizeof(uint8));
	
	f_prop_enum(m_位置索引) = 0;
	f_prop_Save(m_位置索引, 块);

	文件块.m_data = 块->ptr_userData;
	文件块.m_字节数 = 块->count;
	f_file_保存文件块(f, 文件块);
	f_core_array_free((S_Array*)块);
}

C_节点基类* f_node_创建取数组元素节点(S_设备环境& ctx, C_节点树* 子节点树) {
	return new C_取数组元素节点(ctx);
}

C_节点基类* f_node_加载取数组元素节点(S_设备环境& ctx, FILE* f) {
	C_取数组元素节点* node = new C_取数组元素节点(ctx);
	return node;
}

void f_node_保存取数组元素节点(C_节点基类* n, FILE* f) {
	C_取数组元素节点* node = dynamic_cast<C_取数组元素节点*>(n);
}



C_取数组头尾元素节点::C_取数组头尾元素节点(S_设备环境& ctx) : C_节点基类(DEF_取数组头尾元素节点) {
	m_Name = L"取数组头尾元素";
	m_Ctx = ctx;

	C_插座基类* socket;
	DEF_创建数组插座_I(L"数组");
	DEF_创建UI32插座_O(L"元素");

	m_位置索引 = f_alloc_EnumProp(nullptr, {
											{L"尾", ""},
											{L"头", ""},
											{L"弹出尾", ""},
											{L"弹出头", ""},
							  }, L"类型");
	m_位置索引.m_私有 = true;

}

C_取数组头尾元素节点::~C_取数组头尾元素节点() {
	f_prop_Release(m_位置索引);
}

bool C_取数组头尾元素节点::f_update() {
	f_su_插座类型切换到连入的插座类型(this, E_插座方向::e_插座Type_输入, 1);
	auto* socket1 = f_get输入插座(1);

	//uint32 index = *DEF_UI32插座数据(f_get输入插座(2));

	return false;
}

std::string C_取数组头尾元素节点::DEF_节点编译函数{
	m_Code = "";
	m_ReleaseCode = "";
	std::string name = f_getName();


	auto* socket1 = f_get输入插座(1)->f_getLinkOutSocket();

	if (socket1 && f_代码构建_数组指针(socket1)) {
		f_su_插座类型切换到连入的插座类型(this, E_插座方向::e_插座Type_输入, 1);
	}
	else {
		f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输入, 1, E_值类型::e_Type_Array);
		f_get输出插座(1)->f_setCode("");
		std::cout << "error :" << name << "节点输入数据不是数组" << std::endl;
		return "";
	}

	socket1 = f_get输入插座(1);
	if (socket1->f_isLink()) {
		
		auto 数组 = socket1->f_getCode(0);

		auto 元素类型 = f_代码构建_数组元素类型(socket1->m_Type);
		std::string 类型 = f_node_getDataTypeName(元素类型);
		if (类型.empty()) {
			std::cout << "error :" << name << "error 取数组末尾元素 == 元素类型没有实现" << std::endl;
			return "";
		}
		f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输出, 1, 元素类型);

		S_Vec3Array a = S_Vec3Array();
		m_Code += socket1->f_构建变量代码(0);
		if (f_代码构建_是否为数组(元素类型)) {
			m_Code += "static " + 类型 + " " + name + "tmp_reference_none" + " = " + 类型 + "();\n";
			m_Code += 类型 + "* " + name + "tmp_reference = &" + name + "tmp_reference_none;\n";
		}
		else {
			m_Code += 类型 + " " + name + "tmp_reference{};\n";
		}
		


		if (f_prop_enum(m_位置索引) > 1) {
			m_Code += "auto " + name + " = ";
		}
		else {
			m_Code += "auto& " + name + " = ";
		}
		m_Code += 数组 + "->count ? ";


		switch (f_prop_enum(m_位置索引)) {
			case 0: {
				m_Code += "(" + 数组 + "->ptr_userData)[" + 数组 + "->count - 1" + "] : " + name + "tmp_reference;\n";
				break;
			}
			case 1: {
				m_Code += "(" + 数组 + "->ptr_userData)[0] : " + name + "tmp_reference;\n";
				break;
			}

			case 2: {
				m_Code += "(" + 数组 + "->ptr_userData)[" + 数组 + "->count - 1" + "] : " + name + "tmp_reference;\n";
				m_Code += DEF_S(f_core_array_pop_back)"((S_Array*)" + 数组 + ");\n";
				break;
			}
			case 3: {
				m_Code += "(" + 数组 + "->ptr_userData)[0] : " + name + "tmp_reference;\n";
				m_Code += DEF_S(f_core_array_pop_front)"((S_Array*)" + 数组 + ");\n";
				break;
			}
		}
		
		m_Code += m_ReleaseCode;

		f_get输出插座(1)->f_setCode(name);
	}
	else {
		f_get输出插座(1)->f_setCode("");

		f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输入, 1, E_值类型::e_Type_Array);
	}



	if (m_区域父节点) {
		m_区域父节点->m_Code += m_Code;
		return "";
	}

	return m_Code;
}

void C_取数组头尾元素节点::f_读取(FILE* f) {
	C_节点基类::f_读取(f);

	auto 文件块 = f_file_读取文件块(f);
	if (文件块.m_块类型 == E_节点工程文件块类型::e_工程文件块_节点实例属性) {
		const uint8* 下一次读取数据指针 = 文件块.m_data;
		switch (文件块.m_版本号) {
			case 0 << 32 | 1: {
				break;
			}
		}
		下一次读取数据指针 = f_prop_Load(m_位置索引, 下一次读取数据指针);
	}
	free(文件块.m_data);
}

void C_取数组头尾元素节点::f_写入(FILE* f) {
	C_节点基类::f_写入(f);
	auto 文件块 = f_file_构建文件块信息(E_节点工程文件块类型::e_工程文件块_节点实例属性, S_节点数据::g_文件版本号);
	S_UI8Array* 块 = (S_UI8Array*)f_core_array_new(0, sizeof(uint8));

	//f_prop_enum(m_位置索引) = 0;
	f_prop_Save(m_位置索引, 块);

	文件块.m_data = 块->ptr_userData;
	文件块.m_字节数 = 块->count;
	f_file_保存文件块(f, 文件块);
	f_core_array_free((S_Array*)块);
}

C_节点基类* f_node_创建取末尾数组元素节点(S_设备环境& ctx, C_节点树* 子节点树) {
	return new C_取数组头尾元素节点(ctx);
}

C_节点基类* f_node_加载取末尾数组元素节点(S_设备环境& ctx, FILE* f) {
	C_取数组头尾元素节点* node = new C_取数组头尾元素节点(ctx);
	return node;
}

void f_node_保存取末尾数组元素节点(C_节点基类* n, FILE* f) {
	C_取数组头尾元素节点* node = dynamic_cast<C_取数组头尾元素节点*>(n);
}




C_合并数组元素节点::C_合并数组元素节点(S_设备环境& ctx) : C_节点基类(DEF_合并数组元素节点) {
	m_Name = L"合并数组";
	m_Ctx = ctx;

	C_插座基类* socket;
	DEF_创建数组插座_I(L"数组");
	DEF_创建数组插座_I(L"追加数组");
	DEF_创建数组插座_O(L"元素");
}

C_合并数组元素节点::~C_合并数组元素节点() {
}

bool C_合并数组元素节点::f_update() {
	return false;
}

std::string C_合并数组元素节点::DEF_节点编译函数{
	m_Code = "";
	m_ReleaseCode = "";
	std::string name = f_getName();

	//f_su_插座类型切换到连入的插座类型(this, E_插座方向::e_插座Type_输入, 1);
	f_su_插座类型切换到连入的插座类型(this, E_插座方向::e_插座Type_输入, 2);
	auto* socket1 = f_get输入插座(1);
	auto* socket2 = f_get输入插座(2);
	

	m_Code += socket1->f_构建变量代码(0);
	m_Code += socket2->f_构建变量代码(0);
	
	m_Code += DEF_S(S_Array*)" " + name + " = " + DEF_S(f_core_array_from)"((const S_Array*)" + socket1->f_getCode(0) + ");\n";
	m_Code += DEF_S(f_core_array_append)"(" + name + ", (const S_Array*)" + socket2->f_getCode(0) + ");\n";
	m_Code += m_ReleaseCode;
	
	//f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输出, 1, socket2->m_Type);
	f_get输出插座(1)->f_setCode(name);
	if (m_区域父节点) {
		m_区域父节点->m_Code += m_Code;
		m_区域父节点->m_ReleaseCode += f_代码构建_销毁数组(name);
		return "";
	}

	释放 += f_代码构建_销毁数组(name);
	return m_Code;
}

C_节点基类* f_node_创建合并数组元素节点(S_设备环境& ctx, C_节点树* 子节点树) {
	return new C_合并数组元素节点(ctx);
}

C_节点基类* f_node_加载合并数组元素节点(S_设备环境& ctx, FILE* f) {
	C_合并数组元素节点* node = new C_合并数组元素节点(ctx);
	return node;
}

void f_node_保存合并数组元素节点(C_节点基类* n, FILE* f) {
	C_合并数组元素节点* node = dynamic_cast<C_合并数组元素节点*>(n);
}



C_插入数组节点::C_插入数组节点(S_设备环境& ctx) : C_节点基类(DEF_插入数组节点) {
	m_Name = L"追加数组";
	m_Ctx = ctx;

	C_插座基类* socket;
	DEF_创建数组插座_I(L"数组");
	DEF_创建数组插座_I(L"追加数组");
	DEF_创建UI32插座_I(L"偏移");

	DEF_创建数组插座_O(L"元素");

	(DEF_UI32插座数据(f_get输入插座(3))) = -1;
}

C_插入数组节点::~C_插入数组节点() {
}

bool C_插入数组节点::f_update() {
	return false;
}

std::string C_插入数组节点::DEF_节点编译函数{
	m_Code = "";
	m_ReleaseCode = "";
	

	auto* socket1 = f_get输入插座(1);
	auto* socket2 = f_get输入插座(2);
	auto* socket3 = f_get输入插座(3);
	//f_su_插座类型切换到连入的插座类型(this, E_插座方向::e_插座Type_输入, 1);
	if (socket1->f_isLink()) {
		f_su_插座类型切换到连入的插座类型(this, E_插座方向::e_插座Type_输入, 1, E_值类型::e_Type_Array);
	}
	else {
		f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输入, 1, E_值类型::e_Type_Array);
	}
	socket1 = f_get输入插座(1);
	f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输入, 2, socket1->m_Type);
	f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输出, 1, socket1->m_Type);
	socket2 = f_get输入插座(2);
	
	
	
	//std::string name = f_getName();
	//m_Code += DEF_S(S_Array*)" " + name + ";\n";

	m_Code += "{\n";
	m_Code += socket1->f_构建变量代码(0);
	m_Code += socket2->f_构建变量代码(0);
	m_Code += socket3->f_构建变量代码(0);
	std::string name = socket1->f_getCode(0);

	m_Code += DEF_S(f_core_array_insert)"((S_Array*)" + name + ", (const S_Array*)" + socket2->f_getCode(0) + ", " + socket3->f_getCode(0) + ");\n";
	m_Code += m_ReleaseCode;
	m_Code += "}\n";

	
	f_get输出插座(1)->f_setCode(name);
	if (m_区域父节点) {
		m_区域父节点->m_Code += m_Code;
		//m_区域父节点->m_ReleaseCode += f_代码构建_销毁Array(name);
		return "";
	}
	//释放 += f_代码构建_销毁Array(name);
	return m_Code;
}

C_节点基类* f_node_创建插入数组节点(S_设备环境& ctx, C_节点树* 子节点树) {
	return new C_插入数组节点(ctx);
}

C_节点基类* f_node_加载插入数组节点(S_设备环境& ctx, FILE* f) {
	C_插入数组节点* node = new C_插入数组节点(ctx);
	return node;
}

void f_node_保存插入数组节点(C_节点基类* n, FILE* f) {
	C_插入数组节点* node = dynamic_cast<C_插入数组节点*>(n);
}



C_查找数组元素节点::C_查找数组元素节点(S_设备环境& ctx) : C_节点基类(DEF_查找数组元素节点) {
	m_Name = L"查找元素";
	m_Ctx = ctx;

	C_插座基类* socket;
	DEF_创建数组插座_I(L"数组");
	DEF_创建I32插座_I(L"元素");
	DEF_创建I32插座_O(L"索引");

}

C_查找数组元素节点::~C_查找数组元素节点() {
}

bool C_查找数组元素节点::f_update() {
	
	return false;
}

std::string C_查找数组元素节点::DEF_节点编译函数{
	m_Code = "";
	m_ReleaseCode = "";
	std::string name = f_getName();

	auto* socket1 = f_get输入插座(1)->f_getLinkOutSocket();
	if (socket1 && !socket1->f_isLink()) {
		return "";
	}

	if (socket1 && f_代码构建_数组指针(socket1)) {
		f_su_插座类型切换到连入的插座类型(this, E_插座方向::e_插座Type_输入, 1);
	}
	else {
		f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输入, 1, E_值类型::e_Type_Array);
		std::cout << "error :" << name << "节点输入数据不是数组" << std::endl;
		return "";
	}
	socket1 = f_get输入插座(1);


	auto 类型 = f_数组元素插座切换(this, E_插座方向::e_插座Type_输入, 2, socket1->m_Type);
	auto* socket2 = f_get输入插座(2);


	m_Code += DEF_S(int32)" " + name + ";\n";
	m_Code += "{\n";
	m_Code += socket1->f_构建变量代码(0);
	m_Code += socket2->f_构建变量代码(0);

	m_Code += name + " = " + DEF_S(f_core_array_find)"((S_Array*)" + socket1->f_getCode(0) + ", (const uint8*)&(" + socket2->f_getCode(0) + "));\n";

	m_Code += "}\n";

	f_get输出插座(1)->f_setCode(name);
	if (m_区域父节点) {
		m_区域父节点->m_Code += m_Code;
		return "";
	}
	return m_Code;
}

void C_查找数组元素节点::f_读取(FILE* f) {
	C_节点基类::f_读取(f);
	auto 文件块 = f_file_读取文件块(f);

	if (文件块.m_块类型 == E_节点工程文件块类型::e_工程文件块_节点实例属性) {
		const uint8* 下一次读取数据指针 = 文件块.m_data;
		//下一次读取数据指针 = f_prop_Load(m_是否改变原数据, 下一次读取数据指针);
	}

	free(文件块.m_data);
}

void C_查找数组元素节点::f_写入(FILE* f) {
	C_节点基类::f_写入(f);
	auto 文件块 = f_file_构建文件块信息(E_节点工程文件块类型::e_工程文件块_节点实例属性, S_节点数据::g_文件版本号);

	S_UI8Array* 块 = (S_UI8Array*)f_core_array_new(0, sizeof(uint8));
	//f_prop_Save(m_是否改变原数据, 块);

	文件块.m_data = 块->ptr_userData;
	文件块.m_字节数 = 块->count;
	f_file_保存文件块(f, 文件块);
	f_core_array_free((S_Array*)块);
}

C_节点基类* f_node_创建查找数组元素节点(S_设备环境& ctx, C_节点树* 子节点树) {
	return new C_查找数组元素节点(ctx);
}

C_节点基类* f_node_加载查找数组元素节点(S_设备环境& ctx, FILE* f) {
	C_查找数组元素节点* node = new C_查找数组元素节点(ctx);
	return node;
}

void f_node_保存查找数组元素节点(C_节点基类* n, FILE* f) {
	C_查找数组元素节点* node = dynamic_cast<C_查找数组元素节点*>(n);
}




C_I8数组变量节点::C_I8数组变量节点(S_设备环境& ctx) : C_节点基类(DEF_I8数组变量节点) {
	m_Name = L"I8数组";
	m_Ctx = ctx;

	C_插座基类* socket;
	DEF_创建UI32插座_I(L"数量");
	DEF_创建iVec2插座_I(L"范围", nullptr);
	DEF_创建I32插座_I(L"随机种子");

	DEF_创建I8_1D插座_O(L"值");

	m_随机方式 = f_alloc_EnumProp(nullptr, { {L"无", ""}, {L"随机", ""}, {L"区间随机", ""}, {L"区间", ""} }, L"位宽类型");
	m_随机方式.m_私有 = true;
}

C_I8数组变量节点::~C_I8数组变量节点() {
	f_prop_Release(m_随机方式);
}

bool C_I8数组变量节点::f_update() {
	auto* socket1 = f_get输入插座(1);

	uint32 数量 = DEF_UI32插座数据(f_get输入插座(1));
	ivec2 随机区间 = DEF_iVec2插座数据(f_get输入插座(2));
	int32 随机种子 = DEF_I32插座数据(f_get输入插座(3));

	S_I8Array* a = DEF_I8插座_1D数据(f_get输出插座(1), 0);

	f_JIT_重置I8数组(a, 数量, f_prop_enum(m_随机方式), 随机区间, 随机种子);

	return false;
}

std::string	C_I8数组变量节点::DEF_节点编译函数{
	m_Code = "";
	m_ReleaseCode = "";
	std::string name = f_getName();
	C_节点树* rt = f_getThis节点树();


	std::string 随机方式 = f_代码构建_属性变量(m_随机方式, rt);
	auto* socket1 = f_get输入插座(1);
	auto* socket2 = f_get输入插座(2);
	auto* socket3 = f_get输入插座(3);

	if (rt->m_树类型 == E_节点树类型::e_type_着色节点树) {
		m_Code += DEF_S(int)" " + name + " = 0;\n";

	}
	else {
		m_Code += DEF_S(S_I8Array*)" " + name + ";\n";
		m_Code += "{\n";

		m_Code += socket1->f_构建变量代码(0);
		m_Code += socket2->f_构建变量代码(0);
		m_Code += socket3->f_构建变量代码(0);

		m_Code += name + " = " + f_代码构建_创建Array(E_值类型::e_Type_I8_1D, socket1->f_getCode(0));
		m_Code += DEF_S(f_JIT_重置I8数组)"(" + name + ", " + socket1->f_getCode(0) + ", " + f_代码构建_属性变量(m_随机方式, rt) + ", " + socket2->f_getCode(0) + ", " + socket3->f_getCode(0) + ");\n";

		m_Code += m_ReleaseCode;
		m_Code += "}\n";
	}


	f_get输出插座(1)->f_setCode(name);
	if (m_区域父节点) {
		m_区域父节点->m_Code += m_Code;
		m_区域父节点->m_ReleaseCode += f_代码构建_销毁数组(name);
		return "";
	}
	释放 += f_代码构建_销毁数组(name);
	return m_Code;
}

void C_I8数组变量节点::f_读取(FILE* f) {
	C_节点基类::f_读取(f);
	auto 文件块 = f_file_读取文件块(f);

	if (文件块.m_块类型 == E_节点工程文件块类型::e_工程文件块_节点实例属性) {
		const uint8* 下一次读取数据指针 = 文件块.m_data;
		下一次读取数据指针 = f_prop_Load(m_随机方式, 下一次读取数据指针);
	}

	free(文件块.m_data);
}

void C_I8数组变量节点::f_写入(FILE* f) {
	C_节点基类::f_写入(f);
	auto 文件块 = f_file_构建文件块信息(E_节点工程文件块类型::e_工程文件块_节点实例属性, S_节点数据::g_文件版本号);

	S_UI8Array* 块 = (S_UI8Array*)f_core_array_new(0, sizeof(uint8));
	f_prop_Save(m_随机方式, 块);

	文件块.m_data = 块->ptr_userData;
	文件块.m_字节数 = 块->count;
	f_file_保存文件块(f, 文件块);

	f_core_array_free((S_Array*)块);
}

C_节点基类* f_node_创建I8数组变量节点(S_设备环境& ctx, C_节点树* 子节点树) {
	return new C_I8数组变量节点(ctx);
}

C_节点基类* f_node_加载I8数组变量节点(S_设备环境& ctx, FILE* f) {
	C_I8数组变量节点* node = new C_I8数组变量节点(ctx);
	return node;
}

void		f_node_保存I8数组变量节点(C_节点基类* n, FILE* f) {
	C_I8数组变量节点* node = dynamic_cast<C_I8数组变量节点*>(n);
}



C_复制数组节点::C_复制数组节点(S_设备环境& ctx) : C_节点基类(DEF_复制数组节点) {
	m_Name = L"复制数组";
	m_Ctx = ctx;

	C_插座基类* socket;
	DEF_创建数组插座_I(L"数组");
	DEF_创建数组插座_O(L"元素");
}

C_复制数组节点::~C_复制数组节点() {
}

bool C_复制数组节点::f_update() {
	auto* socket1 = f_get输入插座(1);
	auto* outSocket1 = f_get输出插座(1);

	auto* 接入的插座 = socket1->f_getLinkOutSocket();

	S_Array* ad = DEF_数组插座数据(outSocket1);
	f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输入, 1, socket1->f_get接入的数据类型());
	socket1 = f_get输入插座(1);

	//if(socket1->m_Type == E_值类型::e_Type_Array) return false;

	if (接入的插座 && f_代码构建_数组指针(socket1)) {
		f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输出, 1, socket1->m_Type);
		outSocket1 = f_get输出插座(1);
		ad = DEF_数组插座数据(outSocket1);
	}
	else {
		f_core_array_change_elt_size(ad, sizeof(uint8));
		f_core_array_clear(ad);
		return false;
	}
	
	S_Array* as = DEF_数组插座数据(socket1);
	
	f_core_array_change_elt_size(ad, f_core_array_get_elt_size(as));
	f_core_array_copy(ad, as);
	
	return false;
}

std::string C_复制数组节点::DEF_节点编译函数{
	m_Code = "";
	m_ReleaseCode = "";
	std::string name = f_getName();

	auto* socket1 = f_get输入插座(1);
	

	f_su_插座类型切换到连入的插座类型(this, E_插座方向::e_插座Type_输入, 1, E_值类型::e_Type_Array);
	socket1 = f_get输入插座(1);
	if (socket1->m_Type == E_值类型::e_Type_Array) return "";

	if (f_代码构建_数组指针(socket1) == false) {
		return "";
	}
	auto* outSocket1 = f_get输出插座(1);
	auto 类型名称 = f_node_getDataTypeName(socket1->m_Type);
	f_su_切换后端插座类型(this, e_插座Type_输出, 1, socket1->m_Type);


	m_Code += socket1->f_构建变量代码(0);
	m_Code += 类型名称 + "* " + name + " = " + f_代码构建_创建Array(socket1->m_Type, "0");
	m_Code += DEF_S(f_core_array_copy)"((S_Array*)" + name + ", (S_Array*)" + socket1->f_getCode(0) + ");\n";



	f_get输出插座(1)->f_setCode(name);
	if (m_区域父节点) {
		m_区域父节点->m_Code += m_Code;
		m_区域父节点->m_ReleaseCode += f_代码构建_销毁数组(name);
		return "";
	}

	释放 += f_代码构建_销毁数组(name);
	return m_Code;
}

C_节点基类* f_node_创建复制数组节点(S_设备环境& ctx, C_节点树* 子节点树) {
	return new C_复制数组节点(ctx);
}

C_节点基类* f_node_加载复制数组节点(S_设备环境& ctx, FILE* f) {
	C_复制数组节点* node = new C_复制数组节点(ctx);
	return node;
}

void		f_node_保存复制数组节点(C_节点基类* n, FILE* f) {
	C_复制数组节点* node = dynamic_cast<C_复制数组节点*>(n);
}



C_删除数组元素节点::C_删除数组元素节点(S_设备环境& ctx) : C_节点基类(DEF_删除数组元素节点) {
	m_Name = L"删除元素";
	m_Ctx = ctx;

	C_插座基类* socket;
	DEF_创建数组插座_I(L"数组");
	DEF_创建UI32插座_I(L"偏移");
	DEF_创建UI32插座_I(L"数量");
	DEF_创建I8插座_O(L"以删除");
	DEF_创建UI32插座_O(L"剩余");

	DEF_UI32插座数据(f_get输入插座(3)) = 1;


	m_位置索引 = f_alloc_EnumProp(nullptr, {
											{L"索引", ""},
											{L"头", ""},
											{L"尾", ""},
							  }, L"类型");
	m_位置索引.m_私有 = true;
}

C_删除数组元素节点::~C_删除数组元素节点() {
}

bool C_删除数组元素节点::f_update() {
	auto* socket1 = f_get输入插座(1);
	auto* socket2 = f_get输入插座(2);
	auto* socket3 = f_get输入插座(3);

	auto* a = DEF_数组插座数据(socket1);
	int8 是否删除了 = f_core_array_erase(a, DEF_UI32插座数据(socket2), DEF_UI32插座数据(socket3));

	f_get输出插座(1)->f_setData(&是否删除了);
	f_get输出插座(2)->f_setData(&a->count);
	return false;
}

std::string C_删除数组元素节点::DEF_节点编译函数 {
	m_Code = "";
	m_ReleaseCode = "";
	std::string name = f_getName();
	std::string 剩余 = f_getName() + "_剩余";

	auto* socket1 = f_get输入插座(1);
	auto* socket2 = f_get输入插座(2);
	auto* socket3 = f_get输入插座(3);


	m_Code += DEF_S(int8)" " + name + ";\n";
	m_Code += DEF_S(uint8)" " + 剩余 + ";\n";

	m_Code += "{\n";
	m_Code += socket1->f_构建变量代码(0);
	m_Code += socket2->f_构建变量代码(0);
	m_Code += socket3->f_构建变量代码(0);

	m_Code += name + " = " + DEF_S(f_core_array_erase)"((S_Array*)" + socket1->f_getCode(0) + ", " + socket2->f_getCode(0) + ", " + socket3->f_getCode(0) + ");\n";
	m_Code += 剩余 + " = " + "(" + socket1->f_getCode(0) + "->count);\n";

	m_Code += "}\n";


	f_get输出插座(1)->f_setCode(name);
	f_get输出插座(2)->f_setCode(剩余);

	if (m_区域父节点) {
		m_区域父节点->m_Code += m_Code;
		return "";
	}
	return m_Code;
}

void C_删除数组元素节点::f_读取(FILE* f) {
	C_节点基类::f_读取(f);
	auto 文件块 = f_file_读取文件块(f);
	if (文件块.m_块类型 == E_节点工程文件块类型::e_工程文件块_节点实例属性) {
		const uint8* 下一次读取数据指针 = 文件块.m_data;
		switch (文件块.m_版本号) {
			case 0 << 32 | 1: {
				break;
			}
		}
		//f_prop_Load(m_反向, 下一次读取数据指针);
	}
	free(文件块.m_data);
}

void C_删除数组元素节点::f_写入(FILE* f) {
	C_节点基类::f_写入(f);
	auto 文件块 = f_file_构建文件块信息(E_节点工程文件块类型::e_工程文件块_节点实例属性, S_节点数据::g_文件版本号);
	S_UI8Array* 块 = (S_UI8Array*)f_core_array_new(0, sizeof(uint8));
	//f_prop_Save(m_反向, 块);

	文件块.m_data = 块->ptr_userData;
	文件块.m_字节数 = 块->count;
	f_file_保存文件块(f, 文件块);
	f_core_array_free((S_Array*)块);
}

C_节点基类* f_node_创建删除数组元素节点(S_设备环境& ctx, C_节点树* 子节点树) {
	return new C_删除数组元素节点(ctx);
}

C_节点基类* f_node_加载删除数组元素节点(S_设备环境& ctx, FILE* f) {
	C_删除数组元素节点* node = new C_删除数组元素节点(ctx);
	return node;
}

void f_node_保存删除数组元素节点(C_节点基类* n, FILE* f) {
	C_删除数组元素节点* node = dynamic_cast<C_删除数组元素节点*>(n);
}




C_数组元素统计节点::C_数组元素统计节点(S_设备环境& ctx) : C_节点基类(DEF_数组元素统计节点) {
	m_Name = L"数组元素统计";
	m_Ctx = ctx;

	C_插座基类* socket;
	DEF_创建数组插座_I(L"数组");
	DEF_创建引用插座_I(L"元素");
	DEF_创建UI32插座_O(L"数量");

	m_统计类型 = f_alloc_EnumProp(nullptr, {
											{L"值", ""},
											//{L"头", ""},
											//{L"尾", ""},
							  }, L"类型");
	m_统计类型.m_私有 = true;
}

C_数组元素统计节点::~C_数组元素统计节点() {
	f_prop_Release(m_统计类型);
}

bool C_数组元素统计节点::f_update() {
	auto* socket1 = f_get输入插座(1);
	auto* socket2 = f_get输入插座(2);
	auto* socket3 = f_get输入插座(3);

	//int8 是否删除了 = f_core_array_erase(DEF_数组插座数据(socket1), *DEF_UI32插座数据(socket2), *DEF_UI32插座数据(socket3));

	//f_get输出插座(1)->f_setData(&是否删除了);
	return false;
}

std::string C_数组元素统计节点::DEF_节点编译函数{
	m_Code = "";
	m_ReleaseCode = "";
	std::string name = f_getName();

	f_su_插座类型切换到连入的插座类型(this, E_插座方向::e_插座Type_输入, 2);

	auto* socket1 = f_get输入插座(1);
	auto* socket2 = f_get输入插座(2);
	auto* socket3 = f_get输入插座(3);

	

	m_Code += DEF_S(uint32)" " + name + ";\n";

	m_Code += "{\n";
	m_Code += socket1->f_构建变量代码(0);
	m_Code += socket2->f_构建变量代码(0);
	m_Code += socket3->f_构建变量代码(0);

	m_Code += name + " = " + DEF_S(f_core_array_statistics)"((S_Array*)" + socket1->f_getCode(0) + ", (uint8*)&" + socket2->f_getCode(0) + ");\n";

	m_Code += "}\n";


	f_get输出插座(1)->f_setCode(name);

	if (m_区域父节点) {
		m_区域父节点->m_Code += m_Code;
		return "";
	}
	return m_Code;
}

void C_数组元素统计节点::f_读取(FILE* f) {
	C_节点基类::f_读取(f);
	auto 文件块 = f_file_读取文件块(f);
	if (文件块.m_块类型 == E_节点工程文件块类型::e_工程文件块_节点实例属性) {
		const uint8* 下一次读取数据指针 = 文件块.m_data;
		switch (文件块.m_版本号) {
			case 0 << 32 | 1: {
				break;
			}
		}
		下一次读取数据指针 = f_prop_Load(m_统计类型, 下一次读取数据指针);
	}
	free(文件块.m_data);
}

void C_数组元素统计节点::f_写入(FILE* f) {
	C_节点基类::f_写入(f);
	auto 文件块 = f_file_构建文件块信息(E_节点工程文件块类型::e_工程文件块_节点实例属性, S_节点数据::g_文件版本号);
	S_UI8Array* 块 = (S_UI8Array*)f_core_array_new(0, sizeof(uint8));
	
	f_prop_Save(m_统计类型, 块);

	文件块.m_data = 块->ptr_userData;
	文件块.m_字节数 = 块->count;
	f_file_保存文件块(f, 文件块);
	f_core_array_free((S_Array*)块);
}

C_节点基类* f_node_创建数组元素统计节点(S_设备环境& ctx, C_节点树* 子节点树) {
	return new C_数组元素统计节点(ctx);
}

C_节点基类* f_node_加载数组元素统计节点(S_设备环境& ctx, FILE* f) {
	C_数组元素统计节点* node = new C_数组元素统计节点(ctx);
	return node;
}

void f_node_保存数组元素统计节点(C_节点基类* n, FILE* f) {
	C_数组元素统计节点* node = dynamic_cast<C_数组元素统计节点*>(n);
}



